应避免用==比较浮点数,因IEEE 754导致精度丢失;推荐误差容忍法(如Math.abs(a-b)<1e-9)或BigDecimal(字符串构造+compareTo);禁用浮点数作循环条件,位运算方法仅适用于比特级校验。

直接用 == 比较两个 double 或 float 值,大概率出错——这不是 Java 的 bug,而是所有遵循 IEEE 754 标准的语言共有的限制:像 0.1 这样的十进制小数在二进制中无法精确表示,导致 0.1 + 0.2 算出来是 0.30000000000000004,和 0.3 的内存值不一致,== 自然返回 false。关键不是“怎么修”,而是“换思路”。
用误差容忍法替代 == 判断
核心是不追求“完全相等”,而判断“差得够不够小”。推荐写法:
-
Math.abs(a - b) < 1e-9(double类型,通用场景) -
Math.abs(a - b) < 1e-6f(float类型) - 更稳妥的写法(兼顾大数和接近零的情况):
Math.abs(a - b) <= Math.max(Math.abs(a), Math.abs(b)) * 1e-6
金融/金额类场景必须用定点数
业务逻辑对精度零容忍(如账户余额、支付扣款),浮点类型本身就不该出现。此时应彻底避开 float/double:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- Java 中首选
BigDecimal:务必用字符串构造,例如new BigDecimal("19.99"),避免new BigDecimal(19.99)(先失真再封装) - 比较时用
compareTo()方法:bigX.subtract(bigY).compareTo(BigDecimal.ZERO) == 0 - 或统一转为整数单位(如“分”),全程用
long或int运算,输出时再除以 100
别把浮点数当循环条件或索引
以下写法极易失控:
立即学习“Java免费学习笔记(深入)”;
-
for (double x = 0.0; x != 1.0; x += 0.1)——x几乎不可能精确等于1.0,可能死循环或提前退出 - 正确做法:用整数控制次数,浮点值仅用于计算
for (int i = 0; i <= 10; i++) { double x = i * 0.1; } - 条件判断优先用
<=、>=等有序比较,浮点数的大小关系仍是可靠的
不要误用 floatToIntBits / doubleToLongBits
这些方法做的是**位级精确比对**,不是数学近似比较:
-
0.0f和-0.0f判为不等(因符号位不同) - 所有
NaN值判为相等(因 bit 模式相同) -
0.1f + 0.2f和0.3f即使数值接近,bit 不同就返回false - 它适用于序列化校验、自定义
equals()实现等需比特一致的场景,不适用于日常数值逻辑

















