不能直接用 === 比较浮点数,因 ieee 754 表示导致 0.1 + 0.2 === 0.3 为 false;应使用 math.abs(a - b)
直接用
===判断两个浮点数是否相等,常常会出错,因为浮点数在计算机中无法精确表示(比如0.1 + 0.2 !== 0.3)。用Math.abs配合误差容忍值(epsilon),是更可靠的做法。为什么不能直接用 === 比较浮点数
浮点数基于 IEEE 754 标准存储,很多十进制小数(如
0.1)在二进制下是无限循环小数,只能近似存储。运算过程中微小的舍入误差会累积,导致看似相等的计算结果实际不等。
0.1 + 0.2实际得到的是0.300000000000000040.3 === 0.30000000000000004返回false用 Math.abs 实现近似相等判断
核心思路:计算两数之差的绝对值,看是否小于一个极小的阈值(即 epsilon)。这个阈值代表你愿意接受的误差范围。
- 常见 epsilon 值:
Number.EPSILON(约2.22e-16),适合比较接近 0 或 1 的数- 对较大数值或特定场景,建议用相对误差或自定义 epsilon(如
1e-10)- 示例函数:
function floatEqual(a, b, epsilon = Number.EPSILON) {
return Math.abs(a - b) }注意 epsilon 的选择和边界情况
固定 epsilon 不总是安全。比如比较
1000000.0000001和1000000.0000002,差值虽小但可能超过Number.EPSILON;而比较1e-20和0时,Number.EPSILON又显得太大。
- 对数量级差异大的数,可改用相对误差:
Math.abs(a - b)- 涉及
Infinity或NaN时需单独处理(NaN与任何值都不相等,包括自身)- 简单场景用
1e-10或1e-12往往比Number.EPSILON更稳妥实际使用建议
不要为所有数字比较都写一遍
Math.abs逻辑。封装成可复用的工具函数,并根据业务精度要求调整 epsilon。
- 单元测试中浮点比较,推荐用测试框架内置的近似断言(如 Jest 的
toBeCloseTo)- 图形、物理模拟等对精度敏感的场景,明确记录所选 epsilon 并保持一致
- 避免在循环或高频调用中创建闭包或重复计算,优先使用常量 epsilon
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南












