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

Java 四捨五入完全指南:Math.round、BigDecimal 與銀行家算法詳解

     編輯:Java 相關知識

四捨五入看似簡單,但 Math.round(-12.5) 回傳 -12 而非 -13 往往讓開發者措手不及。本文詳細解析 Java 圓整機制、銀行家捨入法(Banker's Rounding)原理、七種 RoundingMode 差異,並提供四種保留小數位實作方案。

經典陷阱:Math.round 的非對稱行為

System.out.println(Math.round(12.5));   // 13
System.out.println(Math.round(-12.5));  // -12  (非 -13)

原因:Math.round 採用 ROUND_HALF_UP 但負數向零方向,實際等同 ROUND_HALF_EVEN 在正數表現,負數卻是 ROUND_HALF_DOWN。

銀行家捨入法(ROUND_HALF_EVEN)

為解決傳統四捨五入在大量資料統計時的偏差(銀行獲利受損),規則如下:

  1. 捨去位 < 5 → 直接捨去。
  2. 捨去位 > 5 → 進位。
  3. 捨去位 = 5:
    • 後面有非零數字 → 進位。
    • 後面全為 0 → 看前一位:奇數進位、偶數捨去。

範例

原值結果說明
11.55611.56六入
11.55411.55四捨
11.555111.56五後有數進位
11.54511.54五後無數,前位 4(偶)捨去
11.55511.56五後無數,前位 5(奇)進位

BigDecimal 七種 RoundingMode 對照

模式行為備註
ROUND_UP遠離零方向只要捨棄位非 0 就進位
ROUND_DOWN趨向零方向直接截斷
ROUND_CEILING向正無窮正數同 UP,負數同 DOWN;Math.round 行為
ROUND_FLOOR向負無窮正數同 DOWN,負數同 UP
HALF_UP四捨五入(5 進)最常用傳統模式
HALF_DOWN五捨六入5 當作捨去
HALF_EVEN銀行家算法IEEE 754 預設、金融推薦

保留小數位四大實作方式

1. BigDecimal + setScale(推薦精確計算)

double f = 111231.5585;
BigDecimal b = new BigDecimal(String.valueOf(f));  // 避免 double 精度誤差
double f1 = b.setScale(2, RoundingMode.HALF_UP).doubleValue();  // 111231.56

2. DecimalFormat(格式化輸出)

java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");
String s = df.format(3.1415926);  // "3.14"

3. String.format / printf

String result = String.format("%.2f", 3.1415926);  // "3.14"
System.out.printf("%.2f%n", 3.1415926);

4. JSP/Struts 標籤(前端顯示)

<bean:write name="entity" property="price" format="0.00" />
<fmt:formatNumber type="number" value="${10000.22/100}" maxFractionDigits="2" />

最佳實踐建議

  • 金融/會計計算:務必使用 BigDecimal + RoundingMode.HALF_EVEN,並以 String 建構子避免二進位浮點誤差。
  • 一般顯示:String.format 或 DecimalFormat 足夠。
  • 避免 直接用 Math.round 處理負數或精確貨幣計算。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved