首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

BigDecimal 精確運算完整指南:構造、運算、格式化與比較

     編輯:Java 綜合教學

為什麼需要 BigDecimal?

float/double 為二進制浮點數,無法精確表示十進制小數(如 0.1),導致商業計算(金額、利率)產生誤差。BigDecimal 提供任意精度十進制運算,專為金融/商業場景設計。

構造器選擇陷阱

核心運算方法(不可變模式)

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

最佳實踐清單

  1. 統一用 String 或 valueOf() 構造
  2. 鏈式調用時注意不可變性:result = a.add(b).multiply(c)
  3. 除法永遠指定 scale + RoundingMode
  4. 比較用 compareTo(),相等判斷用 compareTo(x) == 0
  5. 序列化/持久化建議存儲 toPlainString() 避免科學計數法
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
構造器推薦度說明
new BigDecimal(double)❌ 禁用攜帶 double 二進制誤差(如 new BigDecimal(0.1) → 0.10000000000000000555...)
new BigDecimal(String)✅ 首選精確解析十進制字符串
BigDecimal.valueOf(double)✅ 可用內部用 Double.toString() 轉字符串再解析,避免二進制誤差
new BigDecimal(int/long)✅ 安全整數精確轉換