提问人:Đức hiếu Trần 提问时间:2/1/2023 最后编辑:Jacob IvanovĐức hiếu Trần 更新时间:2/2/2023 访问量:163
Python 中的浮点近似
floating point approximation in python
问:
我是 python 的新手,我正在尝试了解浮点近似以及浮点数在 Python 中的表示方式。
例如:
>>> .1 + .1 + .1 == .3
False
>>> .25 + .25 + .25 == 0.75
True
我理解这两种情况,但是这些具体情况呢?
>>> .1 + .1 + .1 +.1 == .4
True
>>> .1 + .1 == .2
True
难道只是因为 .1+.1+.1+.1 和 .1+.1 的值分别等于 .4 和 .2,即使这些数字在 Python 中没有正确表示,也是巧合吗?是否还有其他类似的情况,或者有什么方法可以识别它们?
谢谢!
答:
简短的回答:是的,这只是一个巧合。
数字在 Python 中表示为 64 位 IEEE 浮点数,也称为双精度。
https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats
编写 Python 时,会找到最接近的 IEEE 编号,表示 .0.3
0.3
当将多个数字相加时,最后一位数字中的这些小错误会累积起来,最终会得到一个不同的数字。有时这种情况发生得更早,有时发生得更晚。有时这些错误会起反作用,但往往不会。
这个答案很好读:
要更深入地了解您的示例,您需要查看这些数字的位表示形式。然而,它变得很复杂,因为人们还需要看看四舍五入和加法是如何工作的......
浮点数在计算机硬件中表示为以 2 为基数(二进制)分数。例如,小数分数 0.125 的值为 1/10 + 2/100 + 5/1000,二进制分数 0.001 的值为 0/2 + 0/4 + 1/8。这两个分数具有相同的值,唯一真正的区别是第一个以 10 为基数的小数表示法,第二个以 2 为基数。
不幸的是,大多数十进制分数不能完全表示为二进制分数。结果是,通常,您输入的十进制浮点数仅由实际存储在计算机中的二进制浮点数近似。
一种幻觉可能会产生另一种幻觉。例如,由于 0.1 不完全是 1/10,因此将 0.1 的三个值相加可能不会恰好得到 0.3:
>>>.1 + .1 + .1 == .3
False
此外,由于 0.1 不能更接近 1/10 的确切值,而 0.3 不能更接近 3/10 的确切值,因此使用 round() 函数进行预舍入也无济于事:
>>>round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1)
False
虽然数字不能更接近其预期的精确值,但 round() 函数可用于四舍五入后,以便具有不精确值的结果相互比较:
>>>round(.1 + .1 + .1, 10) == round(.3, 10)
True
评论
==
1. / 10
1. / 10 * 10
1
floats
doubles