@@ -85,19 +85,34 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y)
8585 (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type))
8686
8787
88- //--- Implementation of the HAVE_PY_SET_53BIT_PRECISION macro -------------
89- //--- defined in pyport.h -------------------------------------------------
88+ //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------
9089//
91- // Give appropriate definitions for the following three macros:
90+ // The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are
91+ // required to support the short float repr introduced in Python 3.1) require
92+ // that the floating-point unit that's being used for arithmetic operations on
93+ // C doubles is set to use 53-bit precision. It also requires that the FPU
94+ // rounding mode is round-half-to-even, but that's less often an issue.
9295//
93- // _Py_SET_53BIT_PRECISION_HEADER : any variable declarations needed to
94- // use the two macros below.
95- // _Py_SET_53BIT_PRECISION_START : store original FPU settings, and
96- // set FPU to 53-bit precision/round-half-to-even
97- // _Py_SET_53BIT_PRECISION_END : restore original FPU settings
96+ // If your FPU isn't already set to 53-bit precision/round-half-to-even, and
97+ // you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should:
98+ //
99+ // #define HAVE_PY_SET_53BIT_PRECISION 1
100+ //
101+ // and also give appropriate definitions for the following three macros:
102+ //
103+ // * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to
104+ // use the two macros below.
105+ // * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and
106+ // set FPU to 53-bit precision/round-half-to-even
107+ // * _Py_SET_53BIT_PRECISION_END: restore original FPU settings
108+ //
109+ // The macros are designed to be used within a single C function: see
110+ // Python/pystrtod.c for an example of their use.
111+
98112
99113// Get and set x87 control word for gcc/x86
100114#ifdef HAVE_GCC_ASM_FOR_X87
115+ #define HAVE_PY_SET_53BIT_PRECISION 1
101116
102117// Functions defined in Python/pymath.c
103118extern unsigned short _Py_get_387controlword (void );
@@ -124,6 +139,7 @@ extern void _Py_set_387controlword(unsigned short);
124139// Get and set x87 control word for VisualStudio/x86.
125140// x87 is not supported in 64-bit or ARM.
126141#if defined(_MSC_VER ) && !defined(_WIN64 ) && !defined(_M_ARM )
142+ #define HAVE_PY_SET_53BIT_PRECISION 1
127143
128144#include <float.h> // __control87_2()
129145
@@ -150,7 +166,10 @@ extern void _Py_set_387controlword(unsigned short);
150166 } while (0)
151167#endif
152168
169+
170+ // MC68881
153171#ifdef HAVE_GCC_ASM_FOR_MC68881
172+ #define HAVE_PY_SET_53BIT_PRECISION 1
154173#define _Py_SET_53BIT_PRECISION_HEADER \
155174 unsigned int old_fpcr, new_fpcr
156175#define _Py_SET_53BIT_PRECISION_START \
@@ -178,6 +197,36 @@ extern void _Py_set_387controlword(unsigned short);
178197#endif
179198
180199
200+ //--- _PY_SHORT_FLOAT_REPR macro -------------------------------------------
201+
202+ // If we can't guarantee 53-bit precision, don't use the code
203+ // in Python/dtoa.c, but fall back to standard code. This
204+ // means that repr of a float will be long (17 significant digits).
205+ //
206+ // Realistically, there are two things that could go wrong:
207+ //
208+ // (1) doubles aren't IEEE 754 doubles, or
209+ // (2) we're on x86 with the rounding precision set to 64-bits
210+ // (extended precision), and we don't know how to change
211+ // the rounding precision.
212+ #if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754 ) && \
213+ !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754 ) && \
214+ !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 )
215+ # define _PY_SHORT_FLOAT_REPR 0
216+ #endif
217+
218+ // Double rounding is symptomatic of use of extended precision on x86.
219+ // If we're seeing double rounding, and we don't have any mechanism available
220+ // for changing the FPU rounding precision, then don't use Python/dtoa.c.
221+ #if defined(X87_DOUBLE_ROUNDING ) && !defined(HAVE_PY_SET_53BIT_PRECISION )
222+ # define _PY_SHORT_FLOAT_REPR 0
223+ #endif
224+
225+ #ifndef _PY_SHORT_FLOAT_REPR
226+ # define _PY_SHORT_FLOAT_REPR 1
227+ #endif
228+
229+
181230#ifdef __cplusplus
182231}
183232#endif
0 commit comments