一、错误 1:用 double
构造 BigDecimal
—— 精度从出生就错了!
❌ 错误代码
BigDecimal bd = new BigDecimal(0.1);
System.out.println(bd);
// 输出:0.1000000000000000055511151231257827021181583404541015625
⚠️ 原因:double 0.1
本身在二进制中就是无限循环小数,构造时已失真。
✅ 正确做法:使用 String
构造
BigDecimal bd = new BigDecimal("0.1");
System.out.println(bd);
// 输出:0.1 ✅
📌 黄金法则:永远使用 String
构造 BigDecimal
,避免 double
参数构造函数!
二、错误 2:equals()
vs compareTo()
—— 你真的懂它们的区别吗?
❌ 错误代码
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
System.out.println(a.equals(b));
// 输出:false ❌
⚠️ 原因:equals()
同时比较值和精度(scale)。1.0
的 scale 是 1,1.00
的 scale 是 2,所以不等。
✅ 正确做法:使用 compareTo()
System.out.println(a.compareTo(b) == 0);
// 输出:true ✅
📌 黄金法则:
- 判断数值相等:用
compareTo(BigDecimal.ZERO) == 0
equals()
仅用于需要严格比较精度的场景(极少)
三、错误 3:除法未指定精度 —— ArithmeticException
爆炸!
❌ 错误代码
BigDecimal result = new BigDecimal("10").divide(new BigDecimal("3"));
// 抛出:java.lang.ArithmeticException: Non-terminating decimal expansion
⚠️ 原因:10 ÷ 3
是无限循环小数,BigDecimal
要求除法必须明确精度和舍入模式。
✅ 正确做法:使用重载的 divide
方法
BigDecimal result = new BigDecimal("10")
.divide(
new BigDecimal("3"),
2, // 保留 2 位小数
RoundingMode.HALF_UP // 四舍五入
);
System.out.println(result);
// 输出:3.33 ✅
📌 黄金法则:任何除法操作都必须指定:
- 小数位数(precision)
- 舍入模式(
RoundingMode
)
四、错误 4:忽略不可变性 —— 修改了“假对象”
❌ 错误代码
BigDecimal total = new BigDecimal("100.00");
total.add(new BigDecimal("50.00")); // 忘记接收返回值
System.out.println(total);
// 输出:100.00 ❌ 期望是 150.00
⚠️ 原因:BigDecimal
是不可变对象,所有计算方法都返回新对象,原对象不变。
✅ 正确做法:接收返回值或链式调用
total = total.add(new BigDecimal("50.00"));
// 或
total = total.add(new BigDecimal("50.00")).subtract(new BigDecimal("10.00"));
System.out.println(total);
// 输出:140.00 ✅
📌 黄金法则:BigDecimal
所有操作都不会改变自身,必须用变量接收结果!