diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2009-04-16 19:52:09 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2009-04-16 19:52:09 (GMT) |
commit | b08a53a99def3fa949643974f713b5b189e21bc7 (patch) | |
tree | 6f7663d510099fd7acfa328ae5a5c88e3eddb1a7 /Include | |
parent | 579b65c2d695eb468fb97568ff7d2ad9d261b2b3 (diff) | |
download | cpython-b08a53a99def3fa949643974f713b5b189e21bc7.zip cpython-b08a53a99def3fa949643974f713b5b189e21bc7.tar.gz cpython-b08a53a99def3fa949643974f713b5b189e21bc7.tar.bz2 |
Issue #1580: use short float repr where possible.
- incorporate and adapt David Gay's dtoa and strtod
into the Python core
- on platforms where we can use Gay's code (almost
all!), repr(float) is based on the shortest
sequence of decimal digits that rounds correctly.
- add sys.float_repr_style attribute to indicate
whether we're using Gay's code or not
- add autoconf magic to detect and enable SSE2
instructions on x86/gcc
- slight change to repr and str: repr switches
to exponential notation at 1e16 instead of
1e17, str switches at 1e11 instead of 1e12
Diffstat (limited to 'Include')
-rw-r--r-- | Include/Python.h | 1 | ||||
-rw-r--r-- | Include/dtoa.h | 15 | ||||
-rw-r--r-- | Include/pymacconfig.h | 6 | ||||
-rw-r--r-- | Include/pymath.h | 5 | ||||
-rw-r--r-- | Include/pyport.h | 47 |
5 files changed, 74 insertions, 0 deletions
diff --git a/Include/Python.h b/Include/Python.h index 76b9503..5b45b38 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -118,6 +118,7 @@ #include "pystrtod.h" #include "pystrcmp.h" +#include "dtoa.h" /* _Py_Mangle is defined in compile.c */ PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); diff --git a/Include/dtoa.h b/Include/dtoa.h new file mode 100644 index 0000000..9b434b7 --- /dev/null +++ b/Include/dtoa.h @@ -0,0 +1,15 @@ +#ifndef PY_NO_SHORT_FLOAT_REPR +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); +PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h index a8679af..7b20431 100644 --- a/Include/pymacconfig.h +++ b/Include/pymacconfig.h @@ -17,6 +17,9 @@ # undef SIZEOF_VOID_P # undef SIZEOF__BOOL # undef WORDS_BIGENDIAN +# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 # undef VA_LIST_IS_ARRAY # if defined(__LP64__) && defined(__x86_64__) @@ -65,6 +68,9 @@ #ifdef __BIG_ENDIAN__ #define WORDS_BIGENDIAN 1 +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +#else +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ diff --git a/Include/pymath.h b/Include/pymath.h index 6ad174d..8872e8a 100644 --- a/Include/pymath.h +++ b/Include/pymath.h @@ -92,6 +92,11 @@ PyAPI_FUNC(double) _Py_force_double(double); # endif #endif +#ifdef HAVE_GCC_ASM_FOR_X87 +PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); +PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); +#endif + /* Py_IS_NAN(X) * Return 1 if float or double arg is a NaN, else 0. * Caution: diff --git a/Include/pyport.h b/Include/pyport.h index bf75d89..ed43569 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -465,6 +465,53 @@ extern "C" { errno = 0; \ } while(0) +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c require that + the FPU is using 53-bit precision. Here are macros that force this. See + Python/pystrtod.c for an example of their use. */ + +#ifdef USING_X87_FPU +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned short old_387controlword, new_387controlword +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + old_387controlword = _Py_get_387controlword(); \ + new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(new_387controlword); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(old_387controlword) +#else +#define _Py_SET_53BIT_PRECISION_HEADER +#define _Py_SET_53BIT_PRECISION_START +#define _Py_SET_53BIT_PRECISION_END +#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 */ +#ifdef X87_DOUBLE_ROUNDING +#define PY_NO_SHORT_FLOAT_REPR +#endif + + /* Py_DEPRECATED(version) * Declare a variable, type, or function deprecated. * Usage: |