浮点数和字符串转换的奇怪行为

2024-04-28

我已将其输入到 python shell 中:

>>> 0.1*0.1
0.010000000000000002

我预计 0.1*0.1 不是 0.01,因为我知道以 10 为底的 0.1 在以 2 为底的情况下是周期性的。

>>> len(str(0.1*0.1))
4

我预计会得到 20 个,因为我在上面看到了 20 个字符。为什么我得到4?

>>> str(0.1*0.1)
'0.01'

好的,这解释了为什么我len给了我 4,但为什么str return '0.01'?

>>> repr(0.1*0.1)
'0.010000000000000002'

为什么str圆但是repr不是? (我读过了这个答案 https://stackoverflow.com/a/2626364/562769,但我想知道他们是如何决定何时str对浮点数进行四舍五入,当它不四舍五入时)

>>> str(0.01) == str(0.0100000000001)
False
>>> str(0.01) == str(0.01000000000001)
True

所以看来是浮点数精度的问题。我认为 Python 会使用 IEEE 754 单精度浮点数。所以我这样检查过:

#include <stdint.h>
#include <stdio.h> // printf

union myUnion {
    uint32_t i; // unsigned integer 32-bit type (on every machine)
    float f;    // a type you want to play with
};

int main() {
    union myUnion testVar;
    testVar.f = 0.01000000000001f;
    printf("%f\n", testVar.f);

    testVar.f = 0.01000000000000002f;
    printf("%f\n", testVar.f);

    testVar.f = 0.01f*0.01f;
    printf("%f\n", testVar.f);
}

I got:

0.010000
0.010000
0.000100

Python 给了我:

>>> 0.01000000000001
0.010000000000009999
>>> 0.01000000000000002
0.010000000000000019
>>> 0.01*0.01
0.0001

为什么 Python 会给我这些结果?

(我使用Python 2.6.5。如果你知道Python版本之间的差异,我也会对它们感兴趣。)


关键要求是repr是它应该往返;那是,eval(repr(f)) == f应该给True在所有情况下。

在 Python 2.x 中(2.7 之前)repr通过做一个工作printf有格式%.17g并丢弃尾随零。 IEEE-754 保证这是正确的(对于 64 位浮点数)。从 2.7 和 3.1 开始,Python 使用了更智能的算法,可以在某些情况下找到更短的表示%.17g给出不必要的非零末端数字或末端九。看3.1 有什么新功能? http://docs.python.org/dev/whatsnew/3.1.html#other-language-changes and 第1580期 http://bugs.python.org/issue1580.

即使在Python 2.7下,repr(0.1 * 0.1) gives "0.010000000000000002"。这是因为0.1 * 0.1 == 0.01 is False根据IEEE-754解析和算术;即,最接近的 64 位浮点值0.1与自身相乘时,生成的 64 位浮点值不是最接近的 64 位浮点值0.01:

>>> 0.1.hex()
'0x1.999999999999ap-4'
>>> (0.1 * 0.1).hex()
'0x1.47ae147ae147cp-7'
>>> 0.01.hex()
'0x1.47ae147ae147bp-7'
                 ^ 1 ulp difference

和...之间的不同repr and str(2.7/3.1 之前)是str具有 12 位小数的格式,而不是 17 位小数,后者不可往返,但在许多情况下会产生更可读的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浮点数和字符串转换的奇怪行为 的相关文章

随机推荐