f浮动时repr(f),str(f),print(f)的精度

f浮动时repr(f),str(f),print(f)的精度,第1张

f浮动时repr(f),str(f),print(f)的精度

TL; DR

str(float)
或的最后一位数字
repr(float)
可能是“错误的”,因为十进制表示似乎没有正确舍入。

>>> 0.1000000000000000401234560.10000000000000003

但是该值仍然比原始值更近

0.1000000000000000
(少1位)。

在的情况下math.pi,pi的十进制近似值为

3.14159265358979 3238463
…,在这种情况下,最后一位是正确的。

在sys.float_info.dig讲述许多十进制数字是如何保证是始终精确。

str(float)
以及
repr(float)Python
3.1+和2.7中的默认输出repr是转换为时float将返回原始值的最短字符串。如有歧义,最后一位四舍五入到最接近的值。浮点数可提供〜15.9的十进制数字精度;但实际上最多需要17位十进制数字的精度才能明确表示53位二进制数,

例如

0.10000000000000004
0x1.999999999999dp-4
和之间
0x1.999999999999cp-4
,但后者更近;这2个具有十进制扩展

0.10000000000000004718447854656915296800434589385986328125

0.100000000000000033306690738754696212708950042724609375

分别。显然后者更接近,因此选择了二进制表示形式。

现在,当使用str()或repr()将它们转换回字符串时,将选择产生完全相同值的最短字符串;对于这两个值,它们分别是0.10000000000000005和0.10000000000000003

doubleIEEE-754中a的精度为53个二进制数字;以十进制表示,您可以通过以10为底的对数2 ^ 53来计算精度,

>>> math.log(2 ** 53, 10)15.954589770191001

表示将近16位精度。该float_info精密告诉你多少总是可以期望得到像样,这个数字是15,因为有一些数字与16个十进制数字是无法区分。

但是,这还不是全部。在Python 3.2+内部发生的是float.__str__和float.__repr__最终调用相同的C方法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 = _PyUnipre_FromASCIi(buf, strlen(buf));    PyMem_Free(buf);    return result;}

在PyOS_double_to_string那以后,在’r’模式(代表再版),电话要么_Py_dg_dtoa与模式0,这是一个内部程序的双重转换为字符串,或snprintf与%17g这些平台对于其_Py_dg_dtoa是行不通的。

行为snprintf完全取决于平台,但是如果_Py_dg_dtoa使用(据我了解,应该在大多数机器上使用),则它应该是可预测的。

在_Py_dg_dtoa模式0被指定为如下:

0 ==>读入并舍入到最接近值时产生d的最短字符串。

因此,这就是发生的情况–产生的字符串double在读入时必须精确地再现该值,并且它必须是可能的最短表示形式,并且在将要读入的多个十进制表示形式中,它是最接近二进制数的表示形式值。现在,这也可能意味着十进制扩展的最后一位数字与以该长度取整的原始值不匹配,只是十进制表示形式尽可能接近原始二进制表示形式。因此,YMMV。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5653096.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存