0.1 + 0.2 === 0.3 返回 false,因二进制浮点数无法精确表示 0.1 和 0.2,实际和为 0.30000000000000004;应使用 number.epsilon 进行容差比较而非直接全等。

JavaScript 中 0.1 + 0.2 === 0.3 返回 false,是因为浮点数在二进制中无法精确表示十进制小数,导致微小的舍入误差。直接用 === 比较会失败。Number.EPSILON 提供了一个安全、标准化的容差基准,帮你合理判断“是否足够接近”。
理解 Number.EPSILON 的含义
Number.EPSILON 是 1 与下一个可表示的浮点数之间的差值(约 2.220446049250313e-16),它代表 JavaScript 双精度浮点数能分辨的最小间隔(在数值 1 附近)。它不是万能误差上限,而是衡量“相对精度”的参考单位。
注意:它不适用于所有数量级的数字——大数的可表示间隔更大,所以实际比较时需结合待比较数值的大小来调整容差。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
用 EPSILON 实现安全的近似相等判断
推荐使用相对误差比较(兼顾大小数),而不是固定容差(如 Math.abs(a - b) ):
- 定义一个通用函数:
function numbersEqual(a, b) {<br> return Math.abs(a - b) } - 解释关键点:
•Math.abs(a - b)是绝对误差
•Math.max(1, |a|, |b|)防止对极小数(如1e-20)过度放大误差影响
• 乘以Number.EPSILON得到该数量级下合理的“可接受误差范围” - 验证:
numbersEqual(0.1 + 0.2, 0.3)→truenumbersEqual(1000000.1, 1000000.2)→false(合理,差值远超精度容限)
何时不该直接用 EPSILON?
Number.EPSILON 本质是为「接近 1 的数」设计的参考值。遇到以下情况需谨慎:
-
比较非常接近 0 的数(如
1e-18和2e-18):此时用Math.abs(a - b) 会过于宽松(因为 EPSILON ≈ 1e-16,比它们还大)。应改用固定小阈值(如 <code>1e-20)或基于目标精度的自定义容差。 -
金融计算等要求确定性精度的场景:浮点数天生不适合钱数运算。应转为整数(单位“分”)或使用
BigInt、专用库(如decimal.js)。 - 需要严格数学相等语义时:比如哈希校验、序列化一致性等,不能容忍任何近似——这时必须避免浮点中间计算,或提前转为字符串/整数处理。
更简洁的实用替代方案(适合多数场景)
如果不想手写容差逻辑,可用现代方法简化:
- 用
Number.isClose()(Stage 3 提案,暂未进入标准,但已有 polyfill) - 快速临时判断:将数字四舍五入到小数点后 10–15 位再比较
function eq(a, b, digits = 10) {<br> const round = (x) => Number(x.toFixed(digits));<br> return round(a) === round(b);<br> }<br> eq(0.1 + 0.2, 0.3); // true
注意:toFixed会转字符串再转回数字,对极大/极小数可能失效,仅建议用于常规小数场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










