bigdecimal的compareto方法忽略标度,只比较数值大小,因此new bigdecimal("1.0").compareto(new bigdecimal("1.00"))返回0;而equals()同时比较数值和标度,故返回false。

BigDecimal 的 compareTo 方法本身就会忽略标度比较数值大小,也就是说,new BigDecimal("1.0").compareTo(new BigDecimal("1.00")) 返回的是 0,表示两者相等。这是它的设计行为,无需额外处理。
为什么 compareTo 本来就不看标度?
compareTo 比较的是**数值大小(value)**,不是字符串形式或精度表示。它底层将两个数转换为统一的 unscaled value 和 scale 后,按数学值对齐再比较,所以 1.0 和 1.00 数学上完全相等,结果必为 0。
哪些方法会受标度影响?
真正会因标度不同而行为不同的,是以下操作:
-
equals():new BigDecimal("1.0").equals(new BigDecimal("1.00"))返回false,因为它同时比较数值和标度 -
==或直接引用比较:显然不行,对象不同 -
scale()、unscaledValue()等获取精度相关属性的方法
需要“忽略标度”时该用什么?
如果你原本在用 equals 却希望语义上等价于数值相等,就该换成 compareTo == 0:
- ✅ 正确写法:
bigA.compareTo(bigB) == 0 - ❌ 避免写法:
bigA.equals(bigB)(除非你明确要标度也一致) - ⚠️ 不推荐强行归一化:
bigA.stripTrailingZeros().equals(bigB.stripTrailingZeros()),多此一举且仍依赖 equals
注意 toString 和构造方式带来的误解
看似一样的字面量,构造方式可能隐含不同标度:
-
new BigDecimal("1.0")→ scale = 1 -
new BigDecimal("1.00")→ scale = 2 -
BigDecimal.valueOf(1.0)→ 实际调用valueOf(1, 0),scale 可能为 0(不推荐用于精确场景)
只要用字符串构造,再用 compareTo,就天然满足“忽略标度比大小”的需求。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











