浮点数直接用==比较会返回false,因二进制表示存在精度误差;应使用误差容差(如1e-10)判断两数之差的绝对值是否小于epsilon。

直接用 == 比较浮点数(如 0.1 + 0.2 == 0.3)会返回 false,这是由二进制浮点表示的固有局限导致的,不是 bug,而是 IEEE 754 标准下的正常现象。可靠比较的关键是**不比绝对相等,而比“足够接近”**。
使用误差容差(epsilon)进行近似比较
最常用、最直观的方法是定义一个极小的容差值(如 1e-10),判断两数之差的绝对值是否小于它:
-
JavaScript 示例:
function floatEqual(a, b, epsilon = 1e-10) { return Math.abs(a - b)
✅floatEqual(0.1 + 0.2, 0.3)→true - 容差值需根据场景选择:科学计算可能用
1e-15,UI 或货币场景用1e-6更稳妥;过大易误判,过小仍失效 - 注意:对极大或极小数值,固定 epsilon 可能不合适,此时应考虑相对误差
相对误差比较(兼顾大小数量级)
当操作数可能非常大(如 1e20)或非常接近零时,仅用绝对误差不够鲁棒。更健壮的方式是结合绝对与相对容差:
- 公式:
Math.abs(a - b) - 常见组合:设
epsilonAbs = 1e-12(兜底小值)、epsilonRel = 1e-12(比例基准) - Python 的
math.isclose(a, b)默认就采用这种策略,推荐优先使用标准库函数
业务场景中优先转整数或定点运算
对精度敏感的领域(如金融计算),根本解法是**避免浮点中间过程**:
- 金额统一用“分”为单位,全部用整数运算:
10 + 20 === 30(代表 0.10 + 0.20 === 0.30 元) - JavaScript 可借助
BigInt或专用库(如decimal.js)做高精度十进制运算 - 输入时立即解析为整数/定点数,全程不走
parseFloat→ 运算 →toFixed这类易出错链路
调试与验证时善用工具辅助
理解为何出错,比单纯修复更重要:
- 用
console.log((0.1).toString(2))查看二进制表示,发现0.1是无限循环二进制小数 - 用
Number.EPSILON理解 JS 中可表示的最小间隔(约2.22e-16),但注意它不等于通用容差 - 单元测试中不要写
expect(0.1 + 0.2).toBe(0.3),改用toBeCloseTo(0.3)(Jest)或自定义断言










