Python浮点数运算精度异常导致判断错误 不使用第三方库如何解决?
浮点数精度比较的原生Python解决方案
你遇到的是二进制浮点数的固有特性:大部分十进制有限小数无法用二进制浮点数精确存储,运算后会产生极微小的尾差,直接用==做等值判断必然不符合预期。以下是无需第三方库的解决方法:
- 方法1:使用内置近似比较函数
Python 3.5及以上版本的math模块自带isclose函数,专门用于浮点数的近似等值判断,默认会自动适配合理的误差容忍阈值:
import math x = 7.68 y = 7.775 z = 7.87 print(math.isclose(y-x, z-y)) # 输出结果为True
如果需要自定义误差范围,可以手动调整rel_tol(相对误差)和abs_tol(绝对误差)参数,例如要求绝对误差不超过1e-6:
print(math.isclose(y-x, z-y, abs_tol=1e-6))
更低版本的Python可以手动实现逻辑:判断两个数差值的绝对值是否小于你能接受的最小误差:
epsilon = 1e-6 print(abs((y-x) - (z-y)) < epsilon) # 输出True
- 方法2:转为定点整数运算
如果你的业务场景有固定的小数位要求(比如金额保留2位、计量保留3位),可以把所有数值乘以10的n次方(n为需要保留的小数位数),四舍五入为整数后再做运算,完全规避浮点误差:
# 本例需要保留3位小数,乘以1000转整数 scale = 10 ** 3 x_int = round(x * scale) y_int = round(y * scale) z_int = round(z * scale) print((y_int - x_int) == (z_int - y_int)) # 输出True
- 方法3:使用标准库decimal模块做精确十进制运算
如果需要完全精确的十进制运算,可以使用Python自带的decimal模块,它按照十进制规则处理数值,不存在二进制浮点数的精度损失问题:
from decimal import Decimal # 注意必须传入字符串形式的数值,避免带入float本身的误差 x = Decimal('7.68') y = Decimal('7.775') z = Decimal('7.87') print((y-x) == (z-y)) # 输出True print(y-x) # 输出精确的0.095
你可以通过getcontext().prec参数自定义全局的运算精度,适配不同的业务需求。
内容的提问来源于stack exchange,提问作者Lvdvig
相关产品推荐
相关产品推荐

