| 構造器 | 推薦度 | 說明 |
new BigDecimal(double) | ❌ 禁用 | 攜帶 double 二進制誤差(如 new BigDecimal(0.1) → 0.10000000000000000555...) |
new BigDecimal(String) | ✅ 首選 | 精確解析十進制字符串 |
BigDecimal.valueOf(double) | ✅ 可用 | 內部用 Double.toString() 轉字符串再解析,避免二進制誤差 |
new BigDecimal(int/long) | ✅ 安全 | 整數精確轉換 |
核心運算方法(不可變模式)
BigDecimal a = new BigDecimal("10.5");
BigDecimal b = new BigDecimal("2.3");
a.add(b); // 12.8
a.subtract(b); // 8.2
a.multiply(b); // 24.15
a.divide(b, 2, RoundingMode.HALF_UP); // 4.57 (指定精度與捨入模式)
關鍵:所有運算返回新對象,原對象不變,必須接收返回值。
除法精度控制
// 不可除盡時必須指定 scale 與 RoundingMode,否則拋 ArithmeticException
BigDecimal div = a.divide(b, 10, RoundingMode.HALF_UP); // 保留 10 位小數,四捨五入
常用捨入模式:HALF_UP(四捨五入)、DOWN(截斷)、CEILING(向正無窮)、FLOOR(向負無窮)。
格式化輸出
NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CHINA); // ¥
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMaximumFractionDigits(2);
BigDecimal loan = new BigDecimal("15000.48");
BigDecimal rate = new BigDecimal("0.008");
BigDecimal interest = loan.multiply(rate); // 120.00384
System.out.println("貸款:" + currency.format(loan)); // ¥15,000.48
System.out.println("利率:" + percent.format(rate)); // 0.80%
System.out.println("利息:" + currency.format(interest)); // ¥120.00
比較大小
BigDecimal a = new BigDecimal("1");
BigDecimal b = new BigDecimal("2");
int cmp = a.compareTo(b); // -1 (a<b), 0 (a==b), 1 (a>b)
// ❌ 禁用 equals() 比較大小:equals 同時比較值與 scale(如 1.0 != 1.00)
效能權衡
- 優點:精確、可控精度、無溢出風險
- 缺點:物件創建開銷大、運算比基本類型慢 1-2 數量級
- 建議:金融核心賬務必用;高頻科學計算、非關鍵路徑可用
double
最佳實踐清單
- 統一用
String 或 valueOf() 構造
- 鏈式調用時注意不可變性:
result = a.add(b).multiply(c)
- 除法永遠指定
scale + RoundingMode
- 比較用
compareTo(),相等判斷用 compareTo(x) == 0
- 序列化/持久化建議存儲
toPlainString() 避免科學計數法
- 上一篇文章: 《瘋狂Java講義》核心知識點精華筆記(上)
- 下一篇文章: Java 字符串全解析:從創建、比較到常用操作實戰
Copyright ©
程式碼之家 All Rights Reserved