Python的浮点数表示样式使用遗留的原因是什么?

2024-04-20 09:08:20 发布

您现在位置:Python中文网/ 问答频道 /正文

在几乎每个系统上,Python都可以为您提供可读的浮点简短表示,而不是17位机器精度:

Python 3.3.0 (default, Dec 20 2014, 13:28:01) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1
0.1
>>> import sys; sys.float_repr_style
'short'

ARM926EJ-S上,您不会得到简短的表示:

^{pr2}$

Python 2.7显然将此简短表示添加到repr(),对于大多数系统

Conversions between floating-point numbers and strings are now correctly rounded on most platforms. These conversions occur in many different places: str() on floats and complex numbers; the float and complexconstructors; numeric formatting; serializing and deserializing floats and complex numbers using the marshal, pickle and json modules; parsing of float and imaginary literals in Python code; and Decimal-to-float conversion.

Related to this, the repr() of a floating-point number x now returns a result based on the shortest decimal string that’s guaranteed to round back to x under correct rounding (with round-half-to-even rounding mode). Previously it gave a string based on rounding x to 17 decimal digits.

The rounding library responsible for this improvement works on Windows and on Unix platforms using the gcc, icc, or suncc compilers. There may be a small number of platforms where correct operation of this code cannot be guaranteed, so the code is not used on such systems. You can find out which code is being used by checking sys.float_repr_style, which will be short if the new code is in use and legacy if it isn’t.

Implemented by Eric Smith and Mark Dickinson, using David Gay’s dtoa.c library; issue 7117.

他们说有些平台不能保证正确的操作(我假设是^{}),但不要说是哪个平台的限制造成了这种情况。在

ARM926EJ-S的什么意思是不能使用short float repr()?在


Tags: andofthetoinonsyscode
1条回答
网友
1楼 · 发布于 2024-04-20 09:08:20

简而言之:这可能不是平台的限制,而是Python构建机制的限制:它没有一种通用的方法来设置浮点计算的53位精度。在

有关详细信息,请查看Python源代码发行版中的^{}文件。以下是摘录:

/* 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

基本上,有两件事会出错。一个是Python配置无法识别C double的浮点格式。这种格式几乎总是ieee754binary64,但有时配置脚本无法确定这一点。这是上面片段中的第一个#if预处理器检查。查看编译时生成的pyconfig.h文件,看看DOUBLE_IS_...宏中是否至少有一个是#defined。或者,在Python提示下尝试此操作:

^{pr2}$

如果你看到类似的东西,这部分应该没问题。如果您看到类似'unknown'的内容,那么Python就无法识别浮点格式。在

第二件可能出错的事情是,我们确实有ieee754binary64格式的双精度,但是Python的构建机制无法确定如何确保这个平台的浮点计算的53位精度。dtoa.c源代码要求我们能够以53位的精度执行所有浮点操作(无论是在硬件还是软件中实现)。对于使用x87浮点单元进行双精度计算的英特尔处理器来说,这是一个特别的问题(与较新的SSE2指令相反):x87的默认精度是64位,使用它进行双精度计算时,默认精度设置会导致double rounding,这打破了dtoa.c的假设。因此,在配置时,构建机器运行一个检查(1)双舍入是否是一个潜在的问题,(2)如果是的话,是否有办法将FPU放入53位精度。现在您需要查看pyconfig.h中的X87_DOUBLE_ROUNDINGHAVE_PY_SET_53BIT_PRECISION宏。在

所以可能是以上两种情况之一。如果非要我猜的话,我猜在那个平台上,双舍入被检测为一个问题,而且不知道如何解决它。这种情况下的解决方案是调整pyport.h以任何平台特定的方式定义_Py_SET_53BIT_PRECISION_*宏,以获得53位精度模式,然后定义HAVE_PY_SET_53BIT_PRECISION。在

相关问题 更多 >