(root)/
Python-3.11.7/
Include/
internal/
pycore_pymath.h
       1  #ifndef Py_INTERNAL_PYMATH_H
       2  #define Py_INTERNAL_PYMATH_H
       3  #ifdef __cplusplus
       4  extern "C" {
       5  #endif
       6  
       7  #ifndef Py_BUILD_CORE
       8  #  error "this header requires Py_BUILD_CORE define"
       9  #endif
      10  
      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 these
      15   * macros after, passing the function result(s) (_Py_ADJUST_ERANGE2 is useful
      16   * for functions returning complex results).  This makes two kinds of
      17   * adjustments to errno:  (A) If it looks like the platform libm set
      18   * errno=ERANGE due to underflow, clear errno. (B) If it looks like the
      19   * platform libm overflowed but didn't set errno, force errno to ERANGE.  In
      20   * effect, we're trying to force a useful implementation of C89 errno
      21   * behavior.
      22   * Caution:
      23   *    This isn't reliable.  C99 no longer requires libm to set errno under
      24   *        any exceptional condition, but does require +- HUGE_VAL return
      25   *        values on overflow.  A 754 box *probably* maps HUGE_VAL to a
      26   *        double infinity, and we're cool if that's so, unless the input
      27   *        was an infinity and an infinity is the expected result.  A C89
      28   *        system sets errno to ERANGE, so we check for that too.  We're
      29   *        out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or
      30   *        if the returned result is a NaN, or if a C89 box returns HUGE_VAL
      31   *        in non-overflow cases.
      32   */
      33  static inline void _Py_ADJUST_ERANGE1(double x)
      34  {
      35      if (errno == 0) {
      36          if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL) {
      37              errno = ERANGE;
      38          }
      39      }
      40      else if (errno == ERANGE && x == 0.0) {
      41          errno = 0;
      42      }
      43  }
      44  
      45  static inline void _Py_ADJUST_ERANGE2(double x, double y)
      46  {
      47      if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL ||
      48          y == Py_HUGE_VAL || y == -Py_HUGE_VAL)
      49      {
      50          if (errno == 0) {
      51              errno = ERANGE;
      52          }
      53      }
      54      else if (errno == ERANGE) {
      55          errno = 0;
      56      }
      57  }
      58  
      59  // Return whether integral type *type* is signed or not.
      60  #define _Py_IntegralTypeSigned(type) \
      61      ((type)(-1) < 0)
      62  
      63  // Return the maximum value of integral type *type*.
      64  #define _Py_IntegralTypeMax(type) \
      65      ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0)
      66  
      67  // Return the minimum value of integral type *type*.
      68  #define _Py_IntegralTypeMin(type) \
      69      ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0)
      70  
      71  // Check whether *v* is in the range of integral type *type*. This is most
      72  // useful if *v* is floating-point, since demoting a floating-point *v* to an
      73  // integral type that cannot represent *v*'s integral part is undefined
      74  // behavior.
      75  #define _Py_InIntegralTypeRange(type, v) \
      76      (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type))
      77  
      78  
      79  //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------
      80  //
      81  // The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are
      82  // required to support the short float repr introduced in Python 3.1) require
      83  // that the floating-point unit that's being used for arithmetic operations on
      84  // C doubles is set to use 53-bit precision.  It also requires that the FPU
      85  // rounding mode is round-half-to-even, but that's less often an issue.
      86  //
      87  // If your FPU isn't already set to 53-bit precision/round-half-to-even, and
      88  // you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should:
      89  //
      90  //     #define HAVE_PY_SET_53BIT_PRECISION 1
      91  //
      92  // and also give appropriate definitions for the following three macros:
      93  //
      94  // * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to
      95  //   use the two macros below.
      96  // * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and
      97  //   set FPU to 53-bit precision/round-half-to-even
      98  // * _Py_SET_53BIT_PRECISION_END: restore original FPU settings
      99  //
     100  // The macros are designed to be used within a single C function: see
     101  // Python/pystrtod.c for an example of their use.
     102  
     103  
     104  // Get and set x87 control word for gcc/x86
     105  #ifdef HAVE_GCC_ASM_FOR_X87
     106  #define HAVE_PY_SET_53BIT_PRECISION 1
     107  
     108  // Functions defined in Python/pymath.c
     109  extern unsigned short _Py_get_387controlword(void);
     110  extern void _Py_set_387controlword(unsigned short);
     111  
     112  #define _Py_SET_53BIT_PRECISION_HEADER                                  \
     113      unsigned short old_387controlword, new_387controlword
     114  #define _Py_SET_53BIT_PRECISION_START                                   \
     115      do {                                                                \
     116          old_387controlword = _Py_get_387controlword();                  \
     117          new_387controlword = (old_387controlword & ~0x0f00) | 0x0200;   \
     118          if (new_387controlword != old_387controlword) {                 \
     119              _Py_set_387controlword(new_387controlword);                 \
     120          }                                                               \
     121      } while (0)
     122  #define _Py_SET_53BIT_PRECISION_END                                     \
     123      do {                                                                \
     124          if (new_387controlword != old_387controlword) {                 \
     125              _Py_set_387controlword(old_387controlword);                 \
     126          }                                                               \
     127      } while (0)
     128  #endif
     129  
     130  // Get and set x87 control word for VisualStudio/x86.
     131  // x87 is not supported in 64-bit or ARM.
     132  #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
     133  #define HAVE_PY_SET_53BIT_PRECISION 1
     134  
     135  #include <float.h>                // __control87_2()
     136  
     137  #define _Py_SET_53BIT_PRECISION_HEADER \
     138      unsigned int old_387controlword, new_387controlword, out_387controlword
     139      // We use the __control87_2 function to set only the x87 control word.
     140      // The SSE control word is unaffected.
     141  #define _Py_SET_53BIT_PRECISION_START                                   \
     142      do {                                                                \
     143          __control87_2(0, 0, &old_387controlword, NULL);                 \
     144          new_387controlword =                                            \
     145            (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \
     146          if (new_387controlword != old_387controlword) {                 \
     147              __control87_2(new_387controlword, _MCW_PC | _MCW_RC,        \
     148                            &out_387controlword, NULL);                   \
     149          }                                                               \
     150      } while (0)
     151  #define _Py_SET_53BIT_PRECISION_END                                     \
     152      do {                                                                \
     153          if (new_387controlword != old_387controlword) {                 \
     154              __control87_2(old_387controlword, _MCW_PC | _MCW_RC,        \
     155                            &out_387controlword, NULL);                   \
     156          }                                                               \
     157      } while (0)
     158  #endif
     159  
     160  
     161  // MC68881
     162  #ifdef HAVE_GCC_ASM_FOR_MC68881
     163  #define HAVE_PY_SET_53BIT_PRECISION 1
     164  #define _Py_SET_53BIT_PRECISION_HEADER \
     165      unsigned int old_fpcr, new_fpcr
     166  #define _Py_SET_53BIT_PRECISION_START                                   \
     167      do {                                                                \
     168          __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr));                \
     169          /* Set double precision / round to nearest.  */                 \
     170          new_fpcr = (old_fpcr & ~0xf0) | 0x80;                           \
     171          if (new_fpcr != old_fpcr) {                                     \
     172                __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr));\
     173          }                                                               \
     174      } while (0)
     175  #define _Py_SET_53BIT_PRECISION_END                                     \
     176      do {                                                                \
     177          if (new_fpcr != old_fpcr) {                                     \
     178              __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr));  \
     179          }                                                               \
     180      } while (0)
     181  #endif
     182  
     183  // Default definitions are empty
     184  #ifndef _Py_SET_53BIT_PRECISION_HEADER
     185  #  define _Py_SET_53BIT_PRECISION_HEADER
     186  #  define _Py_SET_53BIT_PRECISION_START
     187  #  define _Py_SET_53BIT_PRECISION_END
     188  #endif
     189  
     190  
     191  //--- _PY_SHORT_FLOAT_REPR macro -------------------------------------------
     192  
     193  // If we can't guarantee 53-bit precision, don't use the code
     194  // in Python/dtoa.c, but fall back to standard code.  This
     195  // means that repr of a float will be long (17 significant digits).
     196  //
     197  // Realistically, there are two things that could go wrong:
     198  //
     199  // (1) doubles aren't IEEE 754 doubles, or
     200  // (2) we're on x86 with the rounding precision set to 64-bits
     201  //     (extended precision), and we don't know how to change
     202  //     the rounding precision.
     203  #if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
     204      !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
     205      !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
     206  #  define _PY_SHORT_FLOAT_REPR 0
     207  #endif
     208  
     209  // Double rounding is symptomatic of use of extended precision on x86.
     210  // If we're seeing double rounding, and we don't have any mechanism available
     211  // for changing the FPU rounding precision, then don't use Python/dtoa.c.
     212  #if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)
     213  #  define _PY_SHORT_FLOAT_REPR 0
     214  #endif
     215  
     216  #ifndef _PY_SHORT_FLOAT_REPR
     217  #  define _PY_SHORT_FLOAT_REPR 1
     218  #endif
     219  
     220  
     221  #ifdef __cplusplus
     222  }
     223  #endif
     224  #endif /* !Py_INTERNAL_PYMATH_H */