python 浮点不精确

python floating point imprecision

为什么在 python 中,有些计算比其他计算不精确?

例如

x=0.1
y=x+x+x
print(y==0.3)
print(y)

returns

False
0.3000000000004

而如果我以 x 作为 0.25 或 0.5 开始,print(y==0.75)print(y==2.25) 都 return 正确。

Python 的浮点数在内部以基数 2 表示,位数有限(例如 64)。这意味着无法准确存储某些有理数。与 2/3 需要以 10 为基数的无限小数位并最终四舍五入为 0.6666....6667 相同,以 2 为基数的分数(不同的)需要类似类型的舍入。

您可以使用 decimal 模块的 Decimal class 以更熟悉的 base-10 表示形式处理数字。

from decimal import Decimal

x = Decimal("0.1")
y = x+x+x
print(y == Decimal("0.3")) # True
print(y) # 0.3

请注意,我正在从字符串中初始化数字,因为 Decimal(0.3) 会根据已经近似的 0.3 浮点值生成不精确的十进制值。

最后,这只是将问题转移到不同的值,如您在此处所见:

x = Decimal(1)/Decimal(3)
y = x+x+x
print(y) # 0.9999999999999999999999999999

要完全避免有理数的精度问题,您必须使用分数模块。但是你将无法执行某些操作,并且仍然会受到非理性值(以及超越数,例如 π 和 e)的限制。

x = Fraction(1,3)  # 1/3
y = x+x+x
print(y)           # 1

x = Fraction(1,10) # 0.1
y = x+x+x
print(y)           # 3/10
print(float(y))    # 0.3