浮点数不能直接用==比较,因二进制无法精确表示多数十进制小数(如0.1+0.2=0.30000000000000004),导致内存值不等;应使用math.isclose(),其rel_tol适用于数量级接近的数,abs_tol用于接近零或需固定精度的场景。

为什么 == 不能直接比较浮点数
因为浮点数在计算机中以二进制近似存储,像 0.1 + 0.2 实际结果是 0.30000000000000004,而非精确的 0.3。直接用 == 判断会返回 False,即使数学上相等。这不是 Python 特有,而是 IEEE 754 标准下的普遍现象。
math.isclose() 的两个关键参数怎么选
math.isclose(a, b, rel_tol=1e-09, abs_tol=0.0) 默认只看相对误差,但很多实际场景需要两者配合。比如比较接近零的数时,rel_tol 会失效(分母太小),必须靠 abs_tol 托底。
- 当比较值普遍大于
1e-6:用默认rel_tol=1e-09足够,例如math.isclose(1.23456789, 1.23456788) - 当可能涉及
0.0或极小值:显式设置abs_tol=1e-12,例如math.isclose(1e-15, 0.0, abs_tol=1e-12)→True - 做单位换算或物理计算时,按业务精度设
abs_tol,比如毫米级长度比较用abs_tol=1e-3
替代写法的风险:自己写 abs(a - b) 容易出什么错
手动计算差值再比阈值看似简单,但会漏掉数量级差异大的情况。比如 a = 1e10, b = 1e10 + 1,差值是 1.0,若用固定 tol=1e-5 就误判为不等;而 math.isclose() 的 rel_tol 自动按量级缩放,能正确识别这种“相对意义上相等”。
- 固定容差无法适应不同量级数据,硬编码
tol很难兼顾精度和鲁棒性 - 没处理
inf和nan:手动写法遇到math.isclose(float('nan'), 0.0)返回False(合理),但abs(nan - 0) 会抛 <code>ValueError -
math.isclose()对inf有明确定义:math.isclose(float('inf'), float('inf'))是True,手动逻辑需额外分支
测试时怎么避免被浮点误差干扰断言
单元测试里别用 assert a == b 比较计算结果,尤其涉及除法、三角函数、幂运算后。直接换成 assert math.isclose(a, b, abs_tol=1e-10),并根据被测函数输出范围调整 abs_tol。
立即学习“Python免费学习笔记(深入)”;
- 如果函数返回值理论范围是 [0, 1](如概率、归一化值),
abs_tol=1e-9通常安全 - 如果涉及大数累加(如积分、统计和),优先用
rel_tol,比如math.isclose(sum_result, expected, rel_tol=1e-6) - pytest 用户可封装成自定义断言:
assert abs(a - b) ,但不如直接调 <code>math.isclose简洁可靠
真正容易被忽略的是 abs_tol 的必要性——只要数据可能趋近于零,就必须显式指定它,否则 math.isclose(1e-20, 0.0) 会返回 False,即使你本意是“它们在数值计算意义上就是相等的”。


















