Python中Decimal舍入行为疑问:乘法运算精度差异原因咨询
理解Python浮点数的舍入差异问题
这是个特别典型的浮点数二进制表示陷阱问题,咱们一步步拆解清楚:
核心原因:浮点数的二进制存储本质
Python里的float类型遵循IEEE 754双精度标准,它用二进制来存储数值,但大部分十进制小数无法被二进制精确表示——就像你用十进制无法精确表示1/3(0.333...无限循环)一样,二进制对很多十进制小数也是无限循环的,只能存储近似值。
你的两个例子差异,本质是这两个十进制数的二进制近似值,在乘以70后,误差的表现形式不同:
1. 为什么70 × 11.46950得到精确的802.865?
其实11.46950本身也无法被二进制精确存储,但它的近似值乘以70之后,刚好落在了802.865这个十进制数对应的双精度浮点数范围内。你可以亲自验证一下:
print(format(11.4695, '.20f')) # 输出类似 11.46950000000000068212
这个近似值乘以70后,结果的二进制表示刚好和十进制的802.865的二进制表示重合(或者说误差小到在十进制打印时被舍入成了802.865)。
2. 为什么70 × 11.46750得到802.7249999999999?
而11.46750的二进制近似值就没这么“幸运”了:
print(format(11.4675, '.20f')) # 输出类似 11.46749999999999928946
这个略小于11.4675的近似值乘以70后,结果就是802.7249999999999,误差被放大后直接体现在了十进制输出里。
解决办法:用decimal模块做精确十进制计算
如果你的场景需要严格的十进制精度(比如金融计算),别用原生float,改用Python标准库的decimal模块,它直接基于十进制规则处理数值,能避免二进制浮点数的误差:
from decimal import Decimal # 注意要用字符串传入数值,避免float初始化时的误差 result1 = Decimal('70') * Decimal('11.46950') result2 = Decimal('70') * Decimal('11.46750') print(result1) # 输出 802.865 print(result2) # 输出 802.725
简单总结:不是第一个数能被精确表示,只是它的近似误差在计算后刚好没暴露出来;第二个数的误差则在乘法后显现了。这就是浮点数精度问题的典型表现~
内容的提问来源于stack exchange,提问作者pokiman
相关产品推荐
相关产品推荐

