Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
pycore_pymath.h206 linesDownload Raw Back to internal
1#ifndef Py_INTERNAL_PYMATH_H2#define Py_INTERNAL_PYMATH_H3#ifdef __cplusplus4extern "C" {5#endif6 7#ifndef Py_BUILD_CORE8#  error "this header requires Py_BUILD_CORE define"9#endif10 11 12/* _Py_ADJUST_ERANGE1(x)13 * _Py_ADJUST_ERANGE2(x, y)14 * Set errno to 0 before calling a libm function, and invoke one of these15 * macros after, passing the function result(s) (_Py_ADJUST_ERANGE2 is useful16 * for functions returning complex results).  This makes two kinds of17 * adjustments to errno:  (A) If it looks like the platform libm set18 * errno=ERANGE due to underflow, clear errno. (B) If it looks like the19 * platform libm overflowed but didn't set errno, force errno to ERANGE.  In20 * effect, we're trying to force a useful implementation of C89 errno21 * behavior.22 * Caution:23 *    This isn't reliable.  C99 no longer requires libm to set errno under24 *        any exceptional condition, but does require +- HUGE_VAL return25 *        values on overflow.  A 754 box *probably* maps HUGE_VAL to a26 *        double infinity, and we're cool if that's so, unless the input27 *        was an infinity and an infinity is the expected result.  A C8928 *        system sets errno to ERANGE, so we check for that too.  We're29 *        out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or30 *        if the returned result is a NaN, or if a C89 box returns HUGE_VAL31 *        in non-overflow cases.32 */33static inline void _Py_ADJUST_ERANGE1(double x)34{35    if (errno == 0) {36        if (x == Py_INFINITY || x == -Py_INFINITY) {37            errno = ERANGE;38        }39    }40    else if (errno == ERANGE && x == 0.0) {41        errno = 0;42    }43}44 45static inline void _Py_ADJUST_ERANGE2(double x, double y)46{47    if (x == Py_INFINITY || x == -Py_INFINITY ||48        y == Py_INFINITY || y == -Py_INFINITY)49    {50        if (errno == 0) {51            errno = ERANGE;52        }53    }54    else if (errno == ERANGE) {55        errno = 0;56    }57}58 59 60//--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------61//62// The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are63// required to support the short float repr introduced in Python 3.1) require64// that the floating-point unit that's being used for arithmetic operations on65// C doubles is set to use 53-bit precision.  It also requires that the FPU66// rounding mode is round-half-to-even, but that's less often an issue.67//68// If your FPU isn't already set to 53-bit precision/round-half-to-even, and69// you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should:70//71//     #define HAVE_PY_SET_53BIT_PRECISION 172//73// and also give appropriate definitions for the following three macros:74//75// * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to76//   use the two macros below.77// * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and78//   set FPU to 53-bit precision/round-half-to-even79// * _Py_SET_53BIT_PRECISION_END: restore original FPU settings80//81// The macros are designed to be used within a single C function: see82// Python/pystrtod.c for an example of their use.83 84 85// Get and set x87 control word for gcc/x8686#ifdef HAVE_GCC_ASM_FOR_X8787#define HAVE_PY_SET_53BIT_PRECISION 188 89// Functions defined in Python/pymath.c90extern unsigned short _Py_get_387controlword(void);91extern void _Py_set_387controlword(unsigned short);92 93#define _Py_SET_53BIT_PRECISION_HEADER                                  \94    unsigned short old_387controlword, new_387controlword95#define _Py_SET_53BIT_PRECISION_START                                   \96    do {                                                                \97        old_387controlword = _Py_get_387controlword();                  \98        new_387controlword = (old_387controlword & ~0x0f00) | 0x0200;   \99        if (new_387controlword != old_387controlword) {                 \100            _Py_set_387controlword(new_387controlword);                 \101        }                                                               \102    } while (0)103#define _Py_SET_53BIT_PRECISION_END                                     \104    do {                                                                \105        if (new_387controlword != old_387controlword) {                 \106            _Py_set_387controlword(old_387controlword);                 \107        }                                                               \108    } while (0)109#endif110 111// Get and set x87 control word for VisualStudio/x86.112// x87 is not supported in 64-bit or ARM.113#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)114#define HAVE_PY_SET_53BIT_PRECISION 1115 116#include <float.h>                // __control87_2()117 118#define _Py_SET_53BIT_PRECISION_HEADER \119    unsigned int old_387controlword, new_387controlword, out_387controlword120    // We use the __control87_2 function to set only the x87 control word.121    // The SSE control word is unaffected.122#define _Py_SET_53BIT_PRECISION_START                                   \123    do {                                                                \124        __control87_2(0, 0, &old_387controlword, NULL);                 \125        new_387controlword =                                            \126          (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \127        if (new_387controlword != old_387controlword) {                 \128            __control87_2(new_387controlword, _MCW_PC | _MCW_RC,        \129                          &out_387controlword, NULL);                   \130        }                                                               \131    } while (0)132#define _Py_SET_53BIT_PRECISION_END                                     \133    do {                                                                \134        if (new_387controlword != old_387controlword) {                 \135            __control87_2(old_387controlword, _MCW_PC | _MCW_RC,        \136                          &out_387controlword, NULL);                   \137        }                                                               \138    } while (0)139#endif140 141 142// MC68881143#ifdef HAVE_GCC_ASM_FOR_MC68881144#define HAVE_PY_SET_53BIT_PRECISION 1145#define _Py_SET_53BIT_PRECISION_HEADER \146    unsigned int old_fpcr, new_fpcr147#define _Py_SET_53BIT_PRECISION_START                                   \148    do {                                                                \149        __asm__ ("fmove.l %%fpcr,%0" : "=dm" (old_fpcr));               \150        /* Set double precision / round to nearest.  */                 \151        new_fpcr = (old_fpcr & ~0xf0) | 0x80;                           \152        if (new_fpcr != old_fpcr) {                                     \153            __asm__ volatile ("fmove.l %0,%%fpcr" : : "dm" (new_fpcr)); \154        }                                                               \155    } while (0)156#define _Py_SET_53BIT_PRECISION_END                                     \157    do {                                                                \158        if (new_fpcr != old_fpcr) {                                     \159            __asm__ volatile ("fmove.l %0,%%fpcr" : : "dm" (old_fpcr)); \160        }                                                               \161    } while (0)162#endif163 164// Default definitions are empty165#ifndef _Py_SET_53BIT_PRECISION_HEADER166#  define _Py_SET_53BIT_PRECISION_HEADER167#  define _Py_SET_53BIT_PRECISION_START168#  define _Py_SET_53BIT_PRECISION_END169#endif170 171 172//--- _PY_SHORT_FLOAT_REPR macro -------------------------------------------173 174// If we can't guarantee 53-bit precision, don't use the code175// in Python/dtoa.c, but fall back to standard code.  This176// means that repr of a float will be long (17 significant digits).177//178// Realistically, there are two things that could go wrong:179//180// (1) doubles aren't IEEE 754 doubles, or181// (2) we're on x86 with the rounding precision set to 64-bits182//     (extended precision), and we don't know how to change183//     the rounding precision.184#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \185    !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \186    !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)187#  define _PY_SHORT_FLOAT_REPR 0188#endif189 190// Double rounding is symptomatic of use of extended precision on x86.191// If we're seeing double rounding, and we don't have any mechanism available192// for changing the FPU rounding precision, then don't use Python/dtoa.c.193#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)194#  define _PY_SHORT_FLOAT_REPR 0195#endif196 197#ifndef _PY_SHORT_FLOAT_REPR198#  define _PY_SHORT_FLOAT_REPR 1199#endif200 201 202#ifdef __cplusplus203}204#endif205#endif /* !Py_INTERNAL_PYMATH_H */206 
codekingpro/portable-devtools · Team Ai