number.epsilon是1与大于1的最小双精度数之差(≈2.22e-16),仅在数值接近1时有效;工程中需按量级分层设绝对容差(如1e-12)和相对容差(如10×epsilon×max|a,b|),不可直接套用。

Number.EPSILON 本身不是“开箱即用”的精度补偿开关,而是一个基准参考值——它只在数值接近 1 时合理有效。工程级的数值比较需要根据量级、业务容忍度和误差来源做分层处理,不能简单套用 Math.abs(a - b) 。
明确适用边界:它不是万能阈值
Number.EPSILON ≈ 2.22e-16,本质是「1 与大于 1 的最小可表示双精度数之差」。这意味着:
- 当 a、b 在 0.5~2 范围内(如 0.1+0.2 vs 0.3),直接用
Math.abs(a - b) 是可行的 - 当 a 或 b 达到 1e6 以上,Number.EPSILON × 1e6 ≈ 2.22e-10,但此时浮点数实际可分辨的最小间隔已是 ~1e-10 量级,固定乘 1 倍反而过严
- 当 a 或 b 小于 1e-15(比如科学计算中的残差),Number.EPSILON 反而比数值本身还大,会导致所有小数都被判为“相等”
推荐工程实践:混合容差策略
兼顾大小数、防零除、留安全余量,建议统一使用以下模式:
function nearlyEqual(a, b, relativeTolerance = 10, absoluteTolerance = 1e-12) {
const diff = Math.abs(a - b);
// 绝对容差兜底:防止极小数或零附近失效
if (diff
- absoluteTolerance = 1e-12:覆盖接近零的场景(如向量归一化后的误差检查)
- relativeTolerance = 10:相当于允许约 10 倍机器精度的相对偏差,平衡鲁棒性与严格性
- 不直接用
scale = Math.max(1, ...),因为会人为抬高小数的容差门槛
按场景选择容差强度
不同系统对“可接受偏差”的定义差异很大,硬编码一个 epsilon 值容易出问题:
-
UI 动画/布局坐标:用
1e-3级别即可(像素级无感) -
物理仿真或几何计算:常用
1e-6 ~ 1e-8(毫米或微秒级精度) -
金融中间计算:禁用浮点比较,改用整数分(如 cents)或 decimal.js;若必须用浮点,absoluteTolerance 设为
1e-9并配合四舍五入校验 -
科学计算收敛判定:需动态跟踪残差量级,采用
diff / (|a| + |b| + ε)形式的归一化相对误差
避开高频陷阱
这些写法看似简洁,实则隐患明显:
Math.abs(a - b) → 对任何 |a| 或 |b| ≠ 1 的情况都不可靠-
a === b→ 即使是Object.is(0, -0)也暴露语义缺陷,更别说浮点了 Math.abs(a - b) → 若 a 为 0,整个容差坍缩为 0,变成严格相等- 未处理
NaN、Infinity:应在比较前加!isFinite(a) || !isFinite(b)防御











