0
点赞
收藏
分享

微信扫一扫

BigDecimal 的 常见错误

一、错误 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 ✅

📌 黄金法则:任何除法操作都必须指定:

  1. 小数位数(precision)
  2. 舍入模式(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 所有操作都不会改变自身,必须用变量接收结果!

举报

相关推荐

0 条评论