是什么导致Python的float_repr_style使用旧版? [英] What causes Python's float_repr_style to use legacy?

查看:56
本文介绍了是什么导致Python的float_repr_style使用旧版?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

On nearly every system, Python can give you human-readable, short representation of a floating point, not the 17 digit machine-precision:

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 上,您不需要得到简短的表示形式:

On an ARM926EJ-S, you don't get the short representation:

Python 3.3.0 (default, Jun  3 2014, 12:11:19) 
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1
0.10000000000000001
>>> import sys; sys.float_repr_style
'legacy'

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

Python 2.7 apparently added this short representation to repr(), for most systems:

浮点数和字符串之间的转换现在可以在大多数平台上正确舍入.这些转换发生在许多不同的地方:str()代表浮点数和复数;浮动和复杂构造函数;数字格式;使用marshal,pickle和json模块对浮点数和复数进行序列化和反序列化;用Python代码解析float和虚构的文字;和十进制浮点数转换.

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.

与此相关的是,浮点数x的repr()现在基于最短的十进制字符串返回结果,该字符串保证在正确的舍入下使用舍入到四舍五入的方式舍入x. .以前,它根据x舍入到17个十进制数字给出了一个字符串.

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.

负责此改进的舍入库可在Windows和使用gcc,icc或suncc编译器的Unix平台上工作. 在少数平台上,无法保证此代码的正确操作,因此该代码未在此类系统上使用.您可以通过检查sys.float_repr_style来找出正在使用的代码,如果正在使用新代码,它将很短,如果未使用,则将是旧代码.

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.

由Eric Smith和Mark Dickinson实施,使用David Gay的 dtoa.c 库; 问题7117 .

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

他们说某些平台不能保证正确的操作( 我认为),但不要说是哪个平台限制导致了这一点.

They say some platforms can't guarantee correct operation (of dtoa.c I assume), but don't say which platform limitation are the ones that cause this.

关于ARM926EJ-S意味着什么,意味着不能使用短浮点repr()?

What is it about the ARM926EJ-S that means the short float repr() can't be used?

推荐答案

简短的答案:可能不是平台的限制,而是Python构建机制的限制:它没有通用的设置方法53位精度用于浮点计算.

Short answer: it's likely to be not a limitation of the platform, but a limitation of Python's build machinery: it doesn't have a universal way to set 53-bit precision for floating-point computations.

有关更多详细信息,请查看 Include/pyport.h 文件.这是摘录:

For more detail, take a look at the Include/pyport.h file in the Python source distribution. Here's an excerpt:

/* 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的浮点格式.该格式几乎总是IEEE 754 binary64,但有时配置脚本无法弄清楚.这是上面代码段中的第一个#if预处理程序检查.查看在编译时生成的pyconfig.h文件,并查看DOUBLE_IS_...宏中是否至少有一个是#define d.或者,在Python提示符下尝试以下操作:

Essentially, there are two things that can go wrong. One is that the Python configuration fails to identify the floating-point format of a C double. That format is almost always IEEE 754 binary64, but sometimes the config script fails to figure that out. That's the first #if preprocessor check in the snippet above. Look at the pyconfig.h file generated at compile time, and see if at least one of the DOUBLE_IS_... macros is #defined. Alternatively, try this at a Python prompt:

>>> float.__getformat__('double')
'IEEE, little-endian'

如果您看到类似以上的内容,则此部分应该没问题.如果看到类似'unknown'的内容,则说明Python无法识别浮点格式.

If you see something like the above, this part should be okay. If you see something like 'unknown', then Python hasn't managed to identify the floating-point format.

第二个可能出错的地方是,我们确实将IEEE 754 binary64格式加倍,但是Python的构建机制无法弄清楚如何为该平台的浮点计算确保53位精度. dtoa.c源要求我们能够以53位的精度执行所有浮点运算(无论是通过硬件还是软件实现).在使用x87浮点单元进行双精度计算(与较新的SSE2指令相对)的Intel处理器上,这尤其是个问题:x87的默认精度为64位,并将其用于双精度计算使用默认精度设置会导致双舍入,这打破了dtoa.c的假设.因此,在配置时,构建机器会运行检查,以查看(1)是否存在双舍入问题,(2)如果存在,是否有办法将FPU置于53位精度.因此,现在您要查看pyconfig.h中的X87_DOUBLE_ROUNDINGHAVE_PY_SET_53BIT_PRECISION宏.

The second thing that can go wrong is that we do have IEEE 754 binary64 format doubles, but Python's build machinery can't figure out how to ensure 53-bit precision for floating-point computations for this platform. The dtoa.c source requires that we're able to do all floating-point operations (whether implemented in hardware or software) at a precision of 53 bits. That's particularly a problem on Intel processors that are using the x87 floating-point unit for double-precision computations (as opposed to the newer SSE2 instructions): the default precision of the x87 is 64-bits, and using it for double-precision computations with that default precision setting leads to double rounding, which breaks the dtoa.c assumptions. So at config time, the build machinery runs a check to see (1) whether double rounding is a potential problem, and (2) if so, whether there's a way to put the FPU into 53-bit precision. So now you want to look at pyconfig.h for the X87_DOUBLE_ROUNDING and HAVE_PY_SET_53BIT_PRECISION macros.

因此它可能是以上两种情况之一.如果我不得不猜测,我猜想在该平台上,将双取整检测为问题,并且不知道如何解决.在这种情况下,解决方案是采用pyport.h来以任何特定于平台的方式来定义_Py_SET_53BIT_PRECISION_*宏,以获取该53位精度模式,然后再定义HAVE_PY_SET_53BIT_PRECISION.

So it could be either of the above. If I had to guess, I'd guess that on that platform, double rounding is being detected as a problem, and it's not known how to fix it. The solution in that case is to adapt pyport.h to define the _Py_SET_53BIT_PRECISION_* macros in whatever platform-specific way works to get that 53-bit precision mode, and then to define HAVE_PY_SET_53BIT_PRECISION.

这篇关于是什么导致Python的float_repr_style使用旧版?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆