java中直接用==比较浮点数不可靠,因ieee 754二进制近似导致精度误差(如0.1+0.2==0.3为false);应使用epsilon容差比较(如math.abs(a-b)

Java 中直接用 == 比较浮点数(float 或 double)通常不可靠,因为浮点数在计算机中以二进制近似存储,存在精度损失,可能导致本应相等的计算结果在位级别上不一致。
为什么 == 不适合浮点数比较
浮点数遵循 IEEE 754 标准,很多十进制小数(如 0.1)无法被精确表示为二进制小数。例如:
0.1 + 0.2 == 0.3 的结果是 false,因为三者内部的二进制表示存在微小误差。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
推荐做法:使用误差范围(epsilon)比较
判断两个浮点数是否“足够接近”,即差值的绝对值小于一个极小阈值(容差):
- 定义一个合适的 epsilon,例如
1e-6(适用于大多数double场景)或1e-5f(float) - 用
Math.abs(a - b) 替代 <code>a == b - 注意:epsilon 应根据数据量级调整;对极大或极小数值,可考虑相对误差(如
Math.abs(a - b) )
使用标准库工具类
Java 有现成支持,减少出错可能:
-
Double.compare(a, b) == 0:语义上表示“逻辑相等”,但底层仍基于位比较,不解决精度问题,仅用于排序和 null 安全场景 - JDK 1.8+ 提供
Double.equals(a, b):对NaN和正负零做了特殊处理,但仍建议配合 epsilon 使用 - 更稳妥的方式是用
org.apache.commons.lang3.math.NumberUtils中的isEqual(double a, double b, double eps),或自行封装带 epsilon 的工具方法
特殊情况需额外注意
浮点数有特殊值,比较前应明确业务需求:
-
NaN与任何值(包括自身)用==比较都返回false;应使用Double.isNaN(x)单独判断 - 正零(
+0.0)和负零(-0.0)用==判定为 true,但Double.doubleToLongBits()返回不同位模式;若需区分,应显式比较符号位 - 无穷大(
Infinity)可用Double.isInfinite(x)判断,再决定是否允许参与相等比较
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










