@@ -85,19 +85,34 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y)
85
85
(_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type))
86
86
87
87
88
- //--- Implementation of the HAVE_PY_SET_53BIT_PRECISION macro -------------
89
- //--- defined in pyport.h -------------------------------------------------
88
+ //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------
90
89
//
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.
92
95
//
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
+
98
112
99
113
// Get and set x87 control word for gcc/x86
100
114
#ifdef HAVE_GCC_ASM_FOR_X87
115
+ #define HAVE_PY_SET_53BIT_PRECISION 1
101
116
102
117
// Functions defined in Python/pymath.c
103
118
extern unsigned short _Py_get_387controlword (void );
@@ -124,6 +139,7 @@ extern void _Py_set_387controlword(unsigned short);
124
139
// Get and set x87 control word for VisualStudio/x86.
125
140
// x87 is not supported in 64-bit or ARM.
126
141
#if defined(_MSC_VER ) && !defined(_WIN64 ) && !defined(_M_ARM )
142
+ #define HAVE_PY_SET_53BIT_PRECISION 1
127
143
128
144
#include <float.h> // __control87_2()
129
145
@@ -150,7 +166,10 @@ extern void _Py_set_387controlword(unsigned short);
150
166
} while (0)
151
167
#endif
152
168
169
+
170
+ // MC68881
153
171
#ifdef HAVE_GCC_ASM_FOR_MC68881
172
+ #define HAVE_PY_SET_53BIT_PRECISION 1
154
173
#define _Py_SET_53BIT_PRECISION_HEADER \
155
174
unsigned int old_fpcr, new_fpcr
156
175
#define _Py_SET_53BIT_PRECISION_START \
@@ -178,6 +197,36 @@ extern void _Py_set_387controlword(unsigned short);
178
197
#endif
179
198
180
199
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
+
181
230
#ifdef __cplusplus
182
231
}
183
232
#endif
0 commit comments