Java BigDecimal類常用方法


最近工作中接觸到了 Java BigDecimal類,准備整理一下用到的幾個常用方法。

簡介

Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中要用java.math.BigDecimal。BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。

構造器

BigDecimal(int)       創建一個具有參數所指定整數值的對象。
BigDecimal(double) 創建一個具有參數所指定雙精度值的對象。
BigDecimal(long)    創建一個具有參數所指定長整數值的對象。
BigDecimal(String) 創建一個具有參數所指定以字符串表示的數值的對象。

這幾個都是常用的構造器,他們返回的對象都是BigDecimal對象。換而言之, 將各個類型的值轉換為BigDecimal對象,就是通過構造器。

反過來說,將BigDecimal對象轉換為其他類型的對象,我們通過以下幾種:

toString()                將BigDecimal對象的數值轉換成字符串。
doubleValue()          將BigDecimal對象中的值以雙精度數返回。
floatValue()             將BigDecimal對象中的值以單精度數返回。
longValue()             將BigDecimal對象中的值以長整數返回。
intValue()               將BigDecimal對象中的值以整數返回。

常用方法

BigDecimal b1 = new BigDecimal("20");
BigDecimal b2 = new BigDecimal("30");


b1.add(b2) :加法,求兩個BigDecimal類型數據的和。
b1.subtract(b2):減法,求兩個BigDecimal類型數據的差。
b1.multiply(b2):乘法,求兩個BigDecimal類型數據的積。
b1.remainder(b2):求余數,求b1除以b2的余數。
b1.max(b2) : 最大數,求兩個BigDecimal類型數據的最大值
b1.min(b2) : 最小數,求兩個BigDecimal類型數據的最小值。
bi.abs():絕對值,求BigDecimal類型數據的絕對值。
b1.negate():相反數,求BigDecimal類型數據的相反數。

這里把除法單獨拉出來

BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
 

除法 divide有三個參數的方法,第一參數表示除數,第二個參數表示小數點后保留位數,第三個參數表示取舍規則。只有在作除法運算或四舍五入時才用到取舍規則。 因為BigDecimal除法可能出現不能整除的情況,比如 4.5/1.3,這時會報錯java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。所以當我們用三參數的除法方法時,規定了保留幾位小數以及你的保留方式,就可以避免異常。

幾個取舍規則:

ROUND_CEILING //向正無窮方向舍入
ROUND_DOWN //向零方向舍入
ROUND_FLOOR //向負無窮方向舍入
ROUND_HALF_DOWN  //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向下舍入, 例如1.55 保留一位小數結果為1.5
ROUND_HALF_EVEN  //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,如果保留位數是奇數,使用ROUND_HALF_UP,如果是偶數,使用ROUND_HALF_DOWN
ROUND_HALF_UP  //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向上舍入, 1.55保留一位小數結果為1.6
ROUND_UNNECESSARY //計算結果是精確的,不需要舍入模式
ROUND_UP //向遠離0的方向舍入

我們最常用的四舍五入應該是 ROUND_HALF_UP

Note that this is the rounding mode that most of us were taught in grade school.

源碼中的注釋也解釋了這一點。

這里說下除法里的第三個參數,

 a.divide(b,2,RoundingMode.HALF_UP)

這里RoundingMode其實是個枚舉類,點進去源碼可以看到其實他就是匹配到幾種取舍規則

UP(BigDecimal.ROUND_UP),
DOWN(BigDecimal.ROUND_DOWN),
CEILING(BigDecimal.ROUND_CEILING),
FLOOR(BigDecimal.ROUND_FLOOR),
HALF_UP(BigDecimal.ROUND_HALF_UP),
HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);

而最常用的就是 HALF_UP 也就是四舍五入。

那如果我們在乘法或者加法減法中也要保留幾位或者四舍五入,該怎么操作呢?

四舍五入

BigDecimal中有一個setScale()方法

 

 

第一個參數就是你要保留幾位,第二個可填的參數就是取舍規則,圖中的兩種殊途同歸。

如果你第二個參數不加,僅僅想保留幾位,他在源碼中會自動幫你選擇默認的規則。

 public BigDecimal setScale(int newScale) {
        return setScale(newScale, ROUND_UNNECESSARY);
    }

/**
     * Rounding mode to assert that the requested operation has an exact
     * result, hence no rounding is necessary.  If this rounding mode is
     * specified on an operation that yields an inexact result, an
     * {@code ArithmeticException} is thrown.
     */
    public final static int ROUND_UNNECESSARY =  7;

 

源碼中提及,當我們需要精確結果的時候,可以用這種取舍方式,但是如果你的結果不精確就會拋出異常。

栗子:

BigDecimal b1 = new BigDecimal("3.5");    
BigDecimal b2 = new BigDecimal("7.7");
b1.divide(b2).setScale(2);

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    at java.math.BigDecimal.divide(BigDecimal.java:1690)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM