最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java 浮点运算精度:规避 equals 比较
时间:2026-06-18 08:29:03 编辑:袖梨 来源:一聚教程网
<p>Java中浮点数不能用equals()比较,因其按对象语义严格比较值与精度(标度),类型不同或标度不等均返回false;基本类型避免==,因二进制近似导致误差累积;应采用误差阈值法如Math.abs(a - b) < THRESHOLD。</p>
Java 中浮点数不能用 equals() 比较,根本原因在于它不是数值相等判断,而是对象语义的严格比较——既看值,也看精度(即小数位数)。哪怕数学上相等,只要标度不同,equals() 就返回 false。
为什么包装类的 equals() 不可靠
Float 和 Double 的 equals() 方法内部会先检查类型,再比对数值和标度。例如:
-
new Float(0.1f).equals(new Double(0.1))→false(类型不同) -
new Double(1.0).equals(new Double(1.00))→true(Double 标度不参与 equals 判断,但这是特例) -
new BigDecimal("1.0").equals(new BigDecimal("1.00"))→false(标度 1 ≠ 标度 2)
浮点基本类型别用 ==
float/double 是二进制近似表示,0.1 在内存中本就无法精确存储。运算后误差累积,直接 == 极易失败:
-
0.1f + 0.2f == 0.3f→false -
1.0 / 10 == 0.1d→false(float 升级为 double 后,二进制近似值已不同)
正确比较方式:按场景选方法
普通精度容忍场景:用误差阈值
立即学习“Java免费学习笔记(深入)”;
- 定义一个合理
THRESHOLD,比如1e-6(float)或1e-10(double) - 写成
Math.abs(a - b)
金融/高精度场景:用 BigDecimal
- 构造必须用字符串:
new BigDecimal("0.1"),禁用new BigDecimal(0.1) - 比较统一用
compareTo():a.compareTo(b) == 0(只比数值,忽略标度) - 运算全程用
add、subtract、multiply、divide(除法务必指定 scale 和 RoundingMode)
BigDecimal 的 equals() 陷阱
equals() 在 BigDecimal 中是“值 + 标度”双重校验。这意味着:
-
new BigDecimal("1.0").equals(new BigDecimal("1.00"))是false -
new BigDecimal("1.0").compareTo(new BigDecimal("1.00")) == 0是true -
someBigDecimal.equals("1.0")总是false(类型不匹配,不解析字符串)
相关文章
- OpenAI 硬件路线图曝光:第一台硬件没有屏幕,手机 2027 上半年量产 07-31
- 国产大模型,贵到用不起 07-31
- 《王者荣耀》团战雷达解析-赛年标签含义详解 07-31
- 《逐鹿天下手游技能加点攻略》(技能加点策略大揭秘!一文教你玩转逐鹿天下!) 07-31
- 《王者荣耀》艾琳专精装解析-提升普攻与暴击率优势 07-31
- 怎样在Ubuntu VirtualBox中安装Windows 07-31