
本文解释为何 1.0/100.0 == 0.1/10.0 返回 True,而并非浮点数精度“变准”了——这只是特定数值下舍入误差恰好一致的偶然现象,并非普遍规律。
本文解释为何 `1.0/100.0 == 0.1/10.0` 返回 `true`,而并非浮点数精度“变准”了——这只是特定数值下舍入误差恰好一致的偶然现象,并非普遍规律。
在 IEEE 754 双精度浮点数(Python float 和 C double 默认采用)中,十进制小数如 0.1 无法被精确表示,只能以最接近的二进制近似值存储。因此,像 0.1 + 0.2 != 0.3 这类“反直觉”结果是典型表现——不同运算路径引入的舍入误差通常不抵消,导致最终值不同。
但关键在于:误差是否抵消,取决于具体数值和运算顺序。
以 1.0 / 100.0 和 0.1 / 10.0 为例:
-
1.0 / 100.0:100.0是精确可表示的(2^2 × 5^2),除法过程产生一个确定的、唯一的双精度近似值; -
0.1 / 10.0:0.1本身已是近似值(实际存储为0.1000000000000000055511151231257827021181583404541015625),再除以精确的10.0,其舍入结果恰好与前者相同。
这并非数学必然,而是巧合。可通过 Python 交互式环境验证其脆弱性:
>>> 1.0 / 100.0 == 0.1 / 10.0 True >>> 6.0 / 100.0 == 0.6 / 10.0 # 幸运案例 True >>> 7.0 / 100.0 == 0.7 / 10.0 # 不幸案例 False >>> 0.0001 / 100 == 0.00001 / 10 False >>> format(0.0001 / 100, '.20e') '1.00000000000000003643e-06' >>> format(0.00001 / 10, '.20e') '1.00000000000000017764e-06'
可见,仅微小改动(如 6→7 或 0.0001→0.00001)就足以打破相等性。根本原因在于:每个浮点运算都包含独立的舍入步骤(遵循“就近舍入”规则),而多个近似值参与的链式运算,其误差传播路径高度依赖数值的二进制展开结构。
✅ 最佳实践建议:
- 永远避免用
==直接比较浮点数; - 使用相对容差比较:
abs(a - b) ; - Python 标准库推荐
math.isclose(a, b, rel_tol=1e-9); - 若需精确十进制运算(如金融计算),改用
decimal.Decimal。
记住:浮点数不是“不准”,而是按 IEEE 754 精确定义的有理数近似系统——它的行为完全可预测,但绝不可凭直觉假设“看起来一样就真一样”。

















