bigdecimal.equals()比较数值和精度,故1.0与1.00不等;应使用compareto()判断值相等,或统一scale后用equals(),创建时优先用字符串构造并striptrailingzeros()标准化。

这是因为 BigDecimal.equals() 不仅比较数值是否相等,还比较精度(scale)是否一致。1.0 的 scale 是 1,1.00 的 scale 是 2,所以返回 false。
用 compareTo() 替代 equals() 进行数值比较
compareTo() 只关注数值大小,忽略 scale 差异,是判断“值是否相等”的正确方式。
-
new BigDecimal("1.0").compareTo(new BigDecimal("1.00")) == 0→true -
new BigDecimal("1.0").compareTo(new BigDecimal("1.01")) == 0→false - 注意:
compareTo()返回0表示相等,-1表示小于,1表示大于
统一 scale 再用 equals()(适合需保留精度语义的场景)
如果业务逻辑确实依赖 scale(比如金额必须精确到分),可先标准化 scale 再比较:
- 用
setScale(int newScale, RoundingMode)统一小数位数 - 例如:
bd1.setScale(2, HALF_UP).equals(bd2.setScale(2, HALF_UP)) - 注意:必须指定舍入模式,否则可能抛
ArithmeticException
创建时就规范输入,减少后续问题
从源头避免 scale 不一致,更治本:
- 优先用字符串构造:
new BigDecimal("1.0"),避免double构造器引入精度误差 - 对用户输入或数据库读取的数字,解析后立刻调用
stripTrailingZeros()标准化 - 例如:
new BigDecimal("1.00").stripTrailingZeros()→ scale 变为 0,值为1
慎用 double 或 float 构造 BigDecimal
用 new BigDecimal(1.0) 会产生不可预期的 scale 和值(因为 1.0 是 double 字面量,本身有二进制精度问题):
- 错误写法:
new BigDecimal(1.0)→ 实际值可能是0.9999999999999999 - 正确写法:
new BigDecimal("1.0")或BigDecimal.ONE - 如需从浮点数转换,先转成字符串:
new BigDecimal(Double.toString(d))
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











