Python中简单乘除运算调换数字顺序结果不同,该如何解决?
现象原因
该问题是IEEE 754双精度浮点数的二进制存储机制导致的,不属于Python语言的bug,所有遵循该标准的编程语言都会出现同类现象:
十进制下的有限小数,转换为二进制后可能是无限循环小数,双精度浮点数只能保留约15~17位有效数字,剩余部分会被截断,产生微小的精度误差。
- 执行
(1199/1070)*1070时,第一步1199/1070的结果是无限循环的二进制小数,存储时已经产生了微小的精度损失,再乘以1070后误差被暴露,最终输出接近1199但略小的近似值1198.9999999999998 - 执行
(1070/1070)*1199时,第一步1070/1070得到的是可以被二进制精确存储的1.0,后续乘以整数1199不会产生精度损失,因此输出准确值1199.0
解决方法
可根据使用场景选择以下方案避免精度异常:
- 对十进制精度要求高的场景(如金融计算),使用Python内置的
decimal模块做精确十进制运算:
from decimal import Decimal res = (Decimal(1199) / Decimal(1070)) * Decimal(1070) print(float(res)) # 输出 1199.0
- 整数运算场景优先调整运算顺序,先做乘法再做除法,避免中间步骤产生非整浮点值
- 浮点数相等判断不要直接使用
==,改用math.isclose()判断两个值的误差是否在可接受范围内:
import math res = (1199/1070)*1070 print(math.isclose(res, 1199)) # 输出 True
- 对精度要求不高的场景,使用
round()函数对结果做指定小数位的舍入即可。
内容的提问来源于stack exchange,提问作者Saeid Mohammadi Nejati
相关产品推荐
相关产品推荐

