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

Java BigDecimal 高精度計算完全指南:八大捨入模式深度解析

     編輯:Java 相關知識

為什麼需要 BigDecimal?

浮點數陷阱人人知曉:

System.out.println(0.05 + 0.01); // 0.060000000000000005

原因:二進制無法精確表示十進制小數。金融、銀行、電商計價等場景必須使用 BigDecimal。

核心概念

BigDecimal = unscaledValue × 10^(-scale)

  • 非標度值:任意精度整數
  • 標度:小數點右側位數(負數表示科學記數法)

創建對象:避坑指南

方式代碼推薦度說明
double 構造器new BigDecimal(0.1)❌ 禁止攜帶浮點誤差:0.10000000000000000555...
String 構造器new BigDecimal("0.1")✅ 推薦精確表示
valueOf 工廠BigDecimal.valueOf(0.1)✅ 推薦內部用 Double.toString,效果同 String

八大捨入模式詳細對照

調用 setScale(scale, roundingMode) 時指定:

| 模式常量 | 行為描述 | 示例:1.55 → 保留 1 位 | 典型場景 | |----------|----------|------------------------|----------| | ROUND_UP | 遠離零方向 | 1.6 | 稅費計算(向上取整) | | ROUND_DOWN | 趨向零方向(截斷) | 1.5 | 截斷多餘位 | | ROUND_CEILING | 向正無窮 | 1.6 (正) / 1.5 (負) | 保證不小於真值 | | ROUND_FLOOR | 向負無窮 | 1.5 (正) / 1.6 (負) | 保證不大於真值 | | ROUND_HALF_UP | 四捨五入(≥0.5 進位) | 1.6 | **最常用**,貨幣結算 | | ROUND_HALF_DOWN | 五捨六入(>0.5 進位) | 1.5 | 統計學特定需求 | | ROUND_HALF_EVEN | 銀行家算法(五進雙不進) | 1.6 (前位奇) / 1.5 (前位偶) | 減少累積誤差,IEEE 754 默認 | | ROUND_UNNECESSARY | 斷言無需捨入,否則拋異常 | 異常 | 精度校驗 |

實戰最佳實踐

// 金額計算範本
public class MoneyUtils {
    private static final int SCALE = 2;
    private static final RoundingMode MODE = RoundingMode.HALF_UP;

    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        return a.add(b).setScale(SCALE, MODE);
    }

    public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        return a.multiply(b).setScale(SCALE, MODE);
    }

    public static BigDecimal divide(BigDecimal a, BigDecimal b) {
        return a.divide(b, SCALE, MODE);  // 除法必須指定精度與模式
    }
}

常見誤區提醒

  1. 直接用 toString() 輸出:科學記數法顯示,應用 stripTrailingZeros().toPlainString()
  2. equals 比較:比較值+標度,用 compareTo() == 0 比較數值大小
  3. 除法不指定精度:無限循環小數拋 ArithmeticException

總結

BigDecimal 是 Java 高精度計算的基石。牢記:String/valueOf 創建、HALF_UP 計價、divide 必指定精度,即可避開 99% 的坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved