f浮动时repr(f),str(f),print(f)的精度 [英] Precision of repr(f), str(f), print(f) when f is float
问题描述
如果我跑步:
>>> import math
>>> print(math.pi)
3.141592653589793
然后pi以16位数字打印,
Then pi is printed with 16 digits,
但是,根据:
>>> import sys
>>> sys.float_info.dig
15
我的精度是15位数字.
My precision is 15 digits.
所以,我应该依靠该值的最后一位数字(即π的值确实是3.141592653589793nnnnnn).
So, should I rely on the last digit of that value (i.e. that the value of π indeed is 3.141592653589793nnnnnn).
推荐答案
TL; DR
str(float)
或repr(float)
的最后一位数字可能是错误的",因为似乎十进制表示没有正确舍入.
The last digit of str(float)
or repr(float)
can be "wrong" in that it seems that the decimal representation is not correctly rounded.
>>> 0.100000000000000040123456
0.10000000000000003
但是该值仍然比0.1000000000000000
(少1位数字)更接近原始值.
But that value is still closer to the original than 0.1000000000000000
(with 1 digit less) is.
对于math.pi
,pi的十进制近似值为3.14159265358979 3238463 ...,在这种情况下,最后一位是正确的.
In the case of math.pi
, the decimal approximation of pi is 3.141592653589793238463..., in this case the last digit is right.
sys.float_info.dig
告诉您保证始终精确到多少个十进制数字.
The sys.float_info.dig
tells how many decimal digits are guaranteed to be always precise.
Python 3.1+(对于repr
为2.7)中的str(float)
和repr(float)
的默认输出是转换为float
时将返回原始值的最短字符串;如果有歧义,则最后一位四舍五入到最接近的值.浮点数可提供〜15.9的十进制数字精度;但实际上,要明确表示一个53位二进制数,就需要达到17位十进制精度,
The default output for both str(float)
and repr(float)
in Python 3.1+ (and 2.7 for repr
) is the shortest string that when converted to float
will return the original value; in case of ambiguity, the last digit is rounded to the closest value. A float provides ~15.9 decimal digits of precision; but actually up to 17 decimal digit precision is required to represent a 53 binary digits unambiguously,
例如,0.10000000000000004
在0x1.999999999999dp-4
和0x1.999999999999cp-4
之间,但后者更近.这2个具有十进制扩展名
For example 0.10000000000000004
is between 0x1.999999999999dp-4
and 0x1.999999999999cp-4
, but the latter is closer; these 2 have the decimal expansions
0.10000000000000004718447854656915296800434589385986328125
和
0.100000000000000033306690738754696212708950042724609375
分别.显然后者更加接近,因此选择了二进制表示形式.
respectively. Clearly the latter is closer, so that binary representation is chosen.
现在,当使用str()
或repr()
将它们转换回字符串时,将选择产生完全相同值的最短字符串;这两个值分别是0.10000000000000005
和0.10000000000000003
Now when these are converted back to string with str()
, or repr()
, the shortest string that yields the exactly same value is chosen; for these 2 values they are 0.10000000000000005
and 0.10000000000000003
respectively
IEEE-754中double
的精度为53个二进制数字;以十进制表示,您可以通过以10为底的对数2 ^ 53来计算精度
The precision of a double
in IEEE-754 is 53 binary digits; in decimal you can calculate the precision by taking 10-based logarithm of 2^53,
>>> math.log(2 ** 53, 10)
15.954589770191001
表示几乎 16位精度. float_info
精度告诉您总是可以表示多少字符,该数字为15,因为有些数字带有16个十进制数字是无法区分的.
meaning almost 16 digits of precision. The float_info
precision tells how much you can always expect to be presentable, and this number is 15, for there are some numbers with 16 decimal digits that are indistinguishable.
但是,这还不是全部.在Python 3.2+内部发生的事情是float.__str__
和float.__repr__
最终调用相同的C方法
However this is not the whole story. Internally what happens in Python 3.2+ is that the float.__str__
and float.__repr__
end up calling the same C method float_repr
:
float_repr(PyFloatObject *v)
{
PyObject *result;
char *buf;
buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
'r', 0,
Py_DTSF_ADD_DOT_0,
NULL);
if (!buf)
return PyErr_NoMemory();
result = _PyUnicode_FromASCII(buf, strlen(buf));
PyMem_Free(buf);
return result;
}
然后,对于'r'
模式(代表repr),PyOS_double_to_string
要么调用模式0的_Py_dg_dtoa
,它是将双精度型转换为字符串的内部例程,或者使用%17g
用于_Py_dg_dtoa
无法使用的平台.
The PyOS_double_to_string
then, for the 'r'
mode (standing for repr), calls either the _Py_dg_dtoa
with mode 0, which is an internal routine to convert the double to a string, or snprintf
with %17g
for those platforms for which the _Py_dg_dtoa
wouldn't work.
snprintf的行为完全取决于平台,但是如果使用_Py_dg_dtoa
(据我所知,它应该在大多数计算机上使用),则应该是可预测的.
The behaviour snprintf is entirely platform dependent, but if _Py_dg_dtoa
is used (as far as I understand, it should be used on most machines), it should be predictable.
_Py_dg_dtoa
模式0 是指定如下:
The _Py_dg_dtoa
mode 0 is specified as follows:
0 ==>读入并舍入到最接近值时产生d的最短字符串.
0 ==> shortest string that yields d when read in and rounded to nearest.
所以就是这样-产生的字符串在读入时必须精确地再现double
值,并且它必须是可能的最短表示形式,并且在将要读入的多个十进制表示形式中最接近二进制值.现在,这也可能意味着十进制扩展的最后一位数字不与以该长度取整的原始值不匹配,只是十进制表示形式尽可能接近原始二进制表示形式.因此就是YMMV.
So, that is what happens - the yielded string must exactly reproduce the double
value when read in, and it must be the shortest representation possible, and among multiple decimal representations that would be read in, it would be the one that is closest to the binary value. Now, this might also mean that the last digit of decimal expansion does not match the original value rounded at that length, only that the decimal representation is as close to the original binary representation as possible. Thus YMMV.
这篇关于f浮动时repr(f),str(f),print(f)的精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!