BigDecimal運算以及8種捨入模式

2021-10-09 16:23:45 字數 3452 閱讀 7144

bigdecimal是不可變、任意精度的有符號十進位制數。

一般是用在大金額結算等對數值精度要求較高的領域(因為浮點數如float、double表示小數的精確度不足,僅可以處理16位有效數字),但其運算效能低於double、float等,在一般的工程領域數值計算也不會隨便用bigdecimal。

本文將介紹bigdecimal的加減乘除以及8種捨入模式。

有4個常用的建構函式:

這4個建構函式可以將double、long、int、string型別構造為bigdecimal物件。首先推薦使用bigdecimal(string val),其次不推薦使用bigdecimal(double val)來建立,因為double表示0.1就不精確,如果再用new bigdecimal(0.1)得到的數值也還是不精確。它的執行結果如下圖:

建立物件之後的加減乘除運算就不能直接用+、-、*、/ 了,而是用以下方法:

除法divide推薦用下面這個 帶有精確小數字和明確進製方式的api

divide

(bigdecimal divisor,

int scale,

int roundingmode)

bigdecimal a=

newbigdecimal

("1000");

bigdecimal b=

newbigdecimal

("0.001");

//加法: 1000.001

bigdecimal bigdecimal = a.

add(b)

;//減法:999.999

bigdecimal bigdecimal = a.

subtract

(b);

//乘法:1.000

bigdecimal bigdecimal = a.

multiply

(b);

//除法:1000000.000

bigdecimal bigdecimal = a.

divide

(b);

bigdecimal bigdecimal = a.

divide

(b,2

,roundingmode.half_up)

;

值得注意的是,除法一般都是需要確定保留多少位小數的bigdecimal bigdecimal = a.divide(b,2,roundingmode.half_up);,如果不設定保留的小數字scale,就可能會丟擲arithmeticexception異常。這是因為a.divide(b)會預設使用round_unnecessary模式,即不做捨入處理,如果計算結果的小數字和要求保留的小數字不相符,則丟擲異常。

1. round_up

直接進製

bigdecimal.setscale(2,bigdecimal.round_up)

比如:

1000 - 0.011=999.989 

bigdecimal.round_up => 999.99

保留小數點後兩位,第二位的「8」進製成「9」,變成了999.99

2. round_down

捨棄多餘的小數

bigdecimal.

setscale(2

,bigdecimal.round_down)

1000 - 0.011=999.989 

bigdecimal.round_down => 999.98

將第二位以後的「9」捨棄,變成了999.98

3. round_ceiling

往大取值

bigdecimal.

setscale(2

,bigdecimal.round_ceiling)

正負數的處理方式不同:正數進製,負數是捨棄後面的小數

4. round_floor

取小值

bigdecimal.

setscale(2

,bigdecimal.round_floor)

5. round_half_down

五舍六入

bigdecimal.

setscale(2

,bigdecimal.round_half_down)

舉例子:

6. round_half_up

四捨五入

bigdecimal.

setscale(2

,bigdecimal.round_half_up)

比如:

1000-0.006=999.994 -->999.99四捨1000-0.005=999.995 -->1000.00五入

7. round_half_even

這個相對複雜一點

當捨棄的數字<5捨棄,>5進製,=5的時候看情況:

bigdecimal.

setscale(0

,bigdecimal.round_half_even)

在不保留小數點的情況下:

8.round_unnecessary

程式設計師能確定計算結果是精確的,因此不做捨入。但如果最後的數字不滿足保留小數字newscale的要求 會丟擲arithmeticexception。

bigdecimal.

setscale(0

,bigdecimal.round_unnecessary)

在不保留小數的情況下,選擇round_unnecessary策略:

數字執行結果

6.6arithmeticexception

6.06

5.5arithmeticexception

5.05

BigDecimal 簡單運算

一 bigdecimal 加減乘除 bigdecimal bigdecimal new bigdecimal 10000 加法 bigdecimal bigdecimal1 bigdecimal.add new bigdecimal 2000 system.out.println bigdecima...

BigDecimal除法運算報錯

今天在運用bigdecimal做除法運算的時候,錯誤如下 non terminating decimal expansion no exact representable decimal result 不是很明白為什麼會這個樣子,度娘告訴我是因為 bigdecimal 做除法運算,如果除的結果為無限...

BigDecimal的精確運算

float和double型別,執行二進位制浮點運算,數值範圍上精確的近似計算,沒有完全精確的結果,商業計算往往要求結果精確,這時候使bigdecimal。使用bigdecimal做處理,資料來源是double型別要轉化為double.tostring 然後使用string型別的構造器來進行計算 1....