Java中BigDecimal類詳解

前言:float和double只能用來做科學計算或者是工程計算。在商業計算中,對數字精度要求較高,必須使用 BigInteger 類和 BigDecimal 類,它支持任何精度的定點數,可以用它來精確計算貨幣值。

 BigDecimal本身支持基礎的數學計算,可以使用BigDecimal還有一個非常重要的目的,可以利用它來實現準確的四捨五入操作。

1.BigDecimal構造器

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

以上都是比較常用的構造器,他們返回的對象都是BigDecimal對象。換而言之,將各個類型的值轉換爲BigDecimal對象,就是通過構造器。如果想將BigDecimal對象轉換爲其他類型的對象,我們通過以下幾種:

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

2.BigDecimal常用方法

注意,由於一般數值類型,例如double,不能準確地代表16位有效數以上的數字,在使用BigDecimal時,應用 BigDecimal(String)構造器創建對象纔有意義。另外,BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算 符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。 

2.1 加減乘除

  1. 加法:add

  2. 減法:subtract

  3. 乘法:multiply
  4. 除法:divide

代碼示例如下:

package com.example.pdf.test;

import java.math.BigDecimal;

public class Demo3 {

    public static void main(String[] args) {
        BigDecimal b1 = new BigDecimal("10");
        BigDecimal b2 = new BigDecimal("50");
        
        System.out.println("加法,求兩個BigDecimal類型數據的和:"+b1.add(b2));
        System.out.println("減法,求兩個BigDecimal類型數據的差:"+b1.subtract(b2));
        System.out.println("乘法,求兩個BigDecimal類型數據的積:"+b1.multiply(b2));
        System.out.println("求餘數,求b1除以b2的餘數:"+b1.remainder(b2));
        System.out.println("最大數,求兩個BigDecimal類型數據的最大值:"+b1.max(b2));
        System.out.println("最小數,求兩個BigDecimal類型數據的最小值:"+b1.min(b2));
        System.out.println("絕對值,求BigDecimal類型數據的絕對值:"+b1.abs());;
        System.out.println("相反數,求BigDecimal類型數據的相反數:"+b1.negate());;


    }
}

結果如下所示:

除法 divide有三個參數的方法,第一參數表示除數,第二個參數表示小數點後保留位數,第三個參數表示取捨規則。

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

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

我們最常用的四捨五入就是是 ROUND_HALF_UP,下面列幾個比較常見的取捨規則:

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的方向舍入

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

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

2.2 大小比較

package com.example.pdf.test;

import java.math.BigDecimal;

public class Demo3 {

    public static void main(String[] args) {
        BigDecimal a = new BigDecimal(20);
        BigDecimal b  = new BigDecimal(40);
        //前提爲a、b均不能爲null
        if(a.compareTo(b) == -1){
            System.out.println("a小於b");
        }

        if(a.compareTo(b) == 0){
            System.out.println("a等於b");
        }

        if(a.compareTo(b) == 1){
            System.out.println("a大於b");
        }

        if(a.compareTo(b) > -1){
            System.out.println("a大於等於b");
        }

        if(a.compareTo(b) < 1){
            System.out.println("a小於等於b");
        }

    }
}

2.3 四捨五入

setScale()有3個方法,第一個參數就是你要保留幾位,第二個可填的參數就是取捨規則。如果你第二個參數不加,僅僅想保留幾位,會自動幫你選擇默認的規則。

ROUND_UNNECESSARY:計算結果是精確的,不需要舍入模式。

3.數據庫設計

BigDecimal在進行入庫時, 數據庫選擇decimal類型, 長度可以自定義,如10; 小數點我們項目中用的是4, 保留4位小數. 此外還要注意的就是默認值, 一定寫成0.0000, 不要用默認的NULL, 否則在進行加減排序等操作時, 會帶來轉換的麻煩。

numericalValue decimal(10,2) DEFAULT '0.0000' COMMENT '數值',

 

--------------如果大家喜歡我的博客,可以點擊左上角的關注哦。

發佈了48 篇原創文章 · 獲贊 180 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章