Python浮点数运算疑问:为何f值非0而d、g为0?
为什么
f=1-(1/3)-(2/3)的结果不是0.0? 咱们先把你贴的代码再放一遍,方便对照:
>>> a=1/3 >>> b=1/3 >>> c=1/3 >>> d=a+b+c 1.0 >>> f=1-(1/3)-(2/3) 1.1102230246251565e-16 >>> g=1-(1/3+2/3) 0.0
这其实是二进制浮点数精度的经典问题,本质是计算机没法精确表示所有十进制分数——比如1/3,它在二进制里是无限循环的小数,所以存储的时候只能取一个近似值,这个近似值会带着微小的误差。
那为什么g是0.0,f却不是呢?咱们拆解两个表达式的运算顺序:
先看
g=1-(1/3+2/3):
括号里先算1/3 + 2/3,虽然1/3和2/3各自都是近似值,但它们的误差刚好能相互抵消(或者说在浮点运算的舍入规则下,它们的和被精准舍入到了1.0)。接下来1 - 1.0自然就是0.0了。再看
f=1-(1/3)-(2/3):
这里的运算顺序是先算1 - 1/3,得到的是一个近似于2/3的浮点数,但这个值和直接计算2/3得到的浮点数并不完全相等——因为两次运算的误差积累方式不一样。然后用这个近似的2/3减去直接计算的2/3,就会留下一个微小的误差,也就是你看到的1.1102230246251565e-16,这个值是浮点数运算里典型的"机器epsilon"级别的误差,几乎可以看作是浮点数世界里的"0的邻居"。
如果需要完全精确的十进制运算,你可以用Python自带的decimal模块,它能帮你规避这种二进制浮点数的精度问题:
from decimal import Decimal, getcontext getcontext().prec = 20 # 可以根据需求调整精度 one = Decimal(1) third = Decimal(1)/Decimal(3) two_third = Decimal(2)/Decimal(3) f = one - third - two_third print(f) # 输出: 0 g = one - (third + two_third) print(g) # 输出: 0
内容的提问来源于stack exchange,提问作者Rakesh Nara 10
相关产品推荐
相关产品推荐

