diff options
author | Victor Stinner <vstinner@python.org> | 2022-02-23 17:16:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-23 17:16:23 (GMT) |
commit | 9bbdde218005f552304d9954bb97e3f9185edded (patch) | |
tree | 2085d4399dfdcb03bbf9af4c7e5cf92bbdb55f43 /Include/internal/pycore_pymath.h | |
parent | 375a56bd4015596c0cf44129c8842a1fe7199785 (diff) | |
download | cpython-9bbdde218005f552304d9954bb97e3f9185edded.zip cpython-9bbdde218005f552304d9954bb97e3f9185edded.tar.gz cpython-9bbdde218005f552304d9954bb97e3f9185edded.tar.bz2 |
bpo-45412: Add _PY_SHORT_FLOAT_REPR macro (GH-31171)
Remove the HAVE_PY_SET_53BIT_PRECISION macro (moved to the internal
C API).
* Move HAVE_PY_SET_53BIT_PRECISION macro to pycore_pymath.h.
* Replace PY_NO_SHORT_FLOAT_REPR macro with _PY_SHORT_FLOAT_REPR
macro which is always defined. gcc -Wundef emits a warning when
using _PY_SHORT_FLOAT_REPR but the macro is not defined, if
pycore_pymath.h include was forgotten.
Diffstat (limited to 'Include/internal/pycore_pymath.h')
-rw-r--r-- | Include/internal/pycore_pymath.h | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/Include/internal/pycore_pymath.h b/Include/internal/pycore_pymath.h index 395b714..1f54b3d 100644 --- a/Include/internal/pycore_pymath.h +++ b/Include/internal/pycore_pymath.h @@ -85,19 +85,34 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y) (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) -//--- Implementation of the HAVE_PY_SET_53BIT_PRECISION macro ------------- -//--- defined in pyport.h ------------------------------------------------- +//--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------ // -// Give appropriate definitions for the following three macros: +// The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are +// required to support the short float repr introduced in Python 3.1) require +// that the floating-point unit that's being used for arithmetic operations on +// C doubles is set to use 53-bit precision. It also requires that the FPU +// rounding mode is round-half-to-even, but that's less often an issue. // -// _Py_SET_53BIT_PRECISION_HEADER : any variable declarations needed to -// use the two macros below. -// _Py_SET_53BIT_PRECISION_START : store original FPU settings, and -// set FPU to 53-bit precision/round-half-to-even -// _Py_SET_53BIT_PRECISION_END : restore original FPU settings +// If your FPU isn't already set to 53-bit precision/round-half-to-even, and +// you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should: +// +// #define HAVE_PY_SET_53BIT_PRECISION 1 +// +// and also give appropriate definitions for the following three macros: +// +// * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to +// use the two macros below. +// * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and +// set FPU to 53-bit precision/round-half-to-even +// * _Py_SET_53BIT_PRECISION_END: restore original FPU settings +// +// The macros are designed to be used within a single C function: see +// Python/pystrtod.c for an example of their use. + // Get and set x87 control word for gcc/x86 #ifdef HAVE_GCC_ASM_FOR_X87 +#define HAVE_PY_SET_53BIT_PRECISION 1 // Functions defined in Python/pymath.c extern unsigned short _Py_get_387controlword(void); @@ -124,6 +139,7 @@ extern void _Py_set_387controlword(unsigned short); // Get and set x87 control word for VisualStudio/x86. // x87 is not supported in 64-bit or ARM. #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) +#define HAVE_PY_SET_53BIT_PRECISION 1 #include <float.h> // __control87_2() @@ -150,7 +166,10 @@ extern void _Py_set_387controlword(unsigned short); } while (0) #endif + +// MC68881 #ifdef HAVE_GCC_ASM_FOR_MC68881 +#define HAVE_PY_SET_53BIT_PRECISION 1 #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned int old_fpcr, new_fpcr #define _Py_SET_53BIT_PRECISION_START \ @@ -178,6 +197,36 @@ extern void _Py_set_387controlword(unsigned short); #endif +//--- _PY_SHORT_FLOAT_REPR macro ------------------------------------------- + +// If we can't guarantee 53-bit precision, don't use the code +// in Python/dtoa.c, but fall back to standard code. This +// means that repr of a float will be long (17 significant digits). +// +// Realistically, there are two things that could go wrong: +// +// (1) doubles aren't IEEE 754 doubles, or +// (2) we're on x86 with the rounding precision set to 64-bits +// (extended precision), and we don't know how to change +// the rounding precision. +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +# define _PY_SHORT_FLOAT_REPR 0 +#endif + +// Double rounding is symptomatic of use of extended precision on x86. +// If we're seeing double rounding, and we don't have any mechanism available +// for changing the FPU rounding precision, then don't use Python/dtoa.c. +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) +# define _PY_SHORT_FLOAT_REPR 0 +#endif + +#ifndef _PY_SHORT_FLOAT_REPR +# define _PY_SHORT_FLOAT_REPR 1 +#endif + + #ifdef __cplusplus } #endif |