mirror of
https://github.com/python/cpython.git
synced 2025-08-03 08:34:29 +00:00
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.
This commit is contained in:
parent
375a56bd40
commit
9bbdde2180
11 changed files with 104 additions and 96 deletions
|
@ -1,4 +1,3 @@
|
|||
#ifndef PY_NO_SHORT_FLOAT_REPR
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -7,6 +6,11 @@ extern "C" {
|
|||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
|
||||
|
||||
|
||||
#if _PY_SHORT_FLOAT_REPR == 1
|
||||
|
||||
/* These functions are used by modules compiled as C extension like math:
|
||||
they must be exported. */
|
||||
|
||||
|
@ -17,7 +21,8 @@ PyAPI_FUNC(void) _Py_dg_freedtoa(char *s);
|
|||
PyAPI_FUNC(double) _Py_dg_stdnan(int sign);
|
||||
PyAPI_FUNC(double) _Py_dg_infinity(int sign);
|
||||
|
||||
#endif // _PY_SHORT_FLOAT_REPR == 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !PY_NO_SHORT_FLOAT_REPR */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -312,61 +312,6 @@ extern "C" {
|
|||
#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
|
||||
#endif
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* The macros are designed to be used within a single C function: see
|
||||
* Python/pystrtod.c for an example of their use.
|
||||
*/
|
||||
|
||||
// HAVE_PY_SET_53BIT_PRECISION macro must be kept in sync with pycore_pymath.h
|
||||
#ifdef HAVE_GCC_ASM_FOR_X87
|
||||
// Get and set x87 control word for gcc/x86
|
||||
# define HAVE_PY_SET_53BIT_PRECISION 1
|
||||
#endif
|
||||
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
|
||||
// Get and set x87 control word for VisualStudio/x86.
|
||||
// x87 not supported in 64-bit or ARM.
|
||||
# define HAVE_PY_SET_53BIT_PRECISION 1
|
||||
#endif
|
||||
#ifdef HAVE_GCC_ASM_FOR_MC68881
|
||||
# define HAVE_PY_SET_53BIT_PRECISION 1
|
||||
#endif
|
||||
|
||||
|
||||
/* 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 sig 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_NO_SHORT_FLOAT_REPR
|
||||
#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_NO_SHORT_FLOAT_REPR
|
||||
#endif
|
||||
|
||||
|
||||
/* Py_DEPRECATED(version)
|
||||
* Declare a variable, type, or function deprecated.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue