JavaScript中直接用===比较浮点数会出错,如0.1+0.2===0.3返回false,因二进制浮点数无法精确表示某些十进制小数;Number.EPSILON≈2.22e-16,是1附近的最小可表示间隔,用于相对误差判断而非全局容差。

JavaScript中直接用===比较两个浮点数是否相等,常常会出错,比如0.1 + 0.2 === 0.3返回false。这不是JS的bug,而是二进制浮点数表示的固有限制。用Number.EPSILON可以合理判断“近似相等”,但它不是万能解药,需要正确理解其用途和边界。
Number.EPSILON 是什么
Number.EPSILON 是 JavaScript 中定义的常量,值约为 2.220446049250313e-16,代表 1 与大于 1 的最小可表示数之间的差值。它反映的是双精度浮点数在 1 附近能分辨的最小间隔,**不是全局最小误差值**。
它主要用于衡量两个数在相对精度下的“接近程度”,尤其适合做差值与基准值(如 1)比较时的容差参考。
为什么不能直接用 a === b 判断浮点数相等
因为很多十进制小数(如 0.1、0.2)无法被精确表示为二进制浮点数,计算过程会引入微小舍入误差:
立即学习“Java免费学习笔记(深入)”;
-
0.1 + 0.2实际结果是0.30000000000000004 -
0.3实际存储为0.299999999999999988897769753748434595763683319091796875 - 两者差值约
5.55e-17,虽小但不为零,所以===返回false
如何用 Number.EPSILON 做安全的相等判断
核心思路是:判断两数之差的绝对值是否小于某个“可接受的误差范围”。Number.EPSILON 本身适用于数值接近 1 的情况;对其他数量级的数,需按比例缩放容差,常用方法是相对误差比较:
- 基础写法(适用于大多数常规场景):
Math.abs(a - b) —— 仅当 <code>a和b都在 1 附近才可靠 - 更健壮的相对误差判断(推荐):
Math.abs(a - b) - 兼顾极小值的改进版(避免除零或失真):
Math.abs(a - b)
注意:对非常接近 0 的数(如 1e-17),相对误差法可能过于宽松,此时可结合固定容差(如 1e-12)做或运算,即“相对容差或绝对容差取较大者”。
实际使用建议与注意事项
Number.EPSILON 是工具,不是银弹。使用时需注意:
- 它不解决所有精度问题——比如大数相加(
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2)已超出安全整数范围,此时 EPSILON 无意义 - 业务逻辑决定容差大小:金融计算常用
1e-2(分),科学计算可能用1e-10,不要盲目套用EPSILON - 可封装成复用函数,例如:
const numbersEqual = (a, b) => Math.abs(a - b) - 若需严格相等(如哈希、键比较),应提前转为整数(乘以倍数)、用
BigInt或专用库(如 decimal.js)处理










