应使用 Double.compare() 安全比较浮点数大小,它正确处理 NaN、±0.0;需“近似相等”时用 epsilon 误差阈值;高精度场景(如金融)须用 BigDecimal 字符串构造并调用 compareTo()。

Java 中比较浮点数(如 double 或 float)的大小,不能直接用 ==、<、> 等运算符做“精确相等”判断,因为浮点数在二进制中无法精确表示很多十进制小数(比如 0.1),计算过程会引入微小舍入误差。但比较“大小关系”本身是可行的,关键在于避开精度陷阱,选对方法。
用 Double.compare() 安全比较大小关系
这是最推荐、最简洁的方式,专为处理浮点数设计,能正确处理 NaN、+0.0 和 -0.0 等边界情况。
-
Double.compare(a, b)返回负数表示a < b,正数表示a > b,0 表示数学意义上“相等”(即二进制位完全一致,包括处理NaN的逻辑) - 它内部调用了
doubleToLongBits(),绕过了==对NaN的异常行为(NaN == NaN是false,但Double.compare(NaN, NaN) == 0) - 适用于排序、TreeSet/TreeMap 键比较、条件分支中的大小判断等场景
用误差范围(epsilon)判断“近似相等”
当业务逻辑需要判断两个浮点数“是否足够接近”(例如金额校验、物理模拟容差),应避免 ==,改用绝对或相对误差阈值。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 绝对误差:适用于数值量级较稳定的情况,如
Math.abs(a - b) < 1e-10 - 相对误差:更鲁棒,适合跨数量级比较,公式为
Math.abs(a - b) <= Math.max(Math.abs(a), Math.abs(b)) * ε,其中ε通常取1e-12~1e-9 - 注意:不要对接近零的数单独用相对误差,可组合使用(先判绝对误差,再判相对误差)
用 BigDecimal 做高精度比对(尤其涉及金钱)
当精度要求极高(如金融、会计),且原始数据来自字符串输入时,BigDecimal 是唯一可靠选择。
立即学习“Java免费学习笔记(深入)”;
- 构造必须用字符串:
new BigDecimal("0.1"),绝不可用new BigDecimal(0.1)(后者会把 double 的误差带进来) - 比较用
compareTo()方法(返回 -1/0/1),不是equals()(后者会比较 scale,new BigDecimal("1.0").equals(new BigDecimal("1"))是false) - 适合校验、等值断言、精确四则运算,但性能开销大,不建议用于高频循环或实时渲染
慎用原始关系运算符(>、<)的边界情况
单纯判断“大于”或“小于”在多数情况下是安全的,但需警惕几个坑:
-
NaN参与比较时,所有关系运算符都返回false(例如NaN > 5是false,NaN < 5也是false) -
+0.0 == -0.0为true,但Double.compare(+0.0, -0.0)返回0,而某些集合(如HashSet)可能将它们视为不同键 - 极小差异(如
1e-16量级)下,误差可能影响判断结果,此时应优先用Double.compare()

















