BigDecimal 類的使用 1、使用 BigDecimal 的原因 由於需要計算金額,所有需要高精度計算,所有需要使用 BigDecimal 類。 BigDecimal能夠精確的表示一個小數,常用於商業和科學計算;float,double不能精確的表示一個小數。 2、常用 ...
BigDecimal 類的使用
1、使用 BigDecimal 的原因
由於需要計算金額,所有需要高精度計算,所有需要使用 BigDecimal 類。
BigDecimal能夠精確的表示一個小數,常用於商業和科學計算;float,double不能精確的表示一個小數。
2、常用方法
2.1 加法(add)
分別用兩種不同的數據類型(long 和 string)創建 BigDecimal 對象;
import java.math.BigDecimal;
public class BigDecimalTest {
/**
* 使用BigDecimal,參數類型是double類型,計算還是不精確
*/
@Test
public void testAdd1(){
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.add(b2));
//輸出:0.06000000000000000298372437868010820238851010799407958984375
}
/**
* 使用BigDecimal,參數類型是String類型,計算結果精確
*/
@Test
public void testAdd2(){
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.add(b2));
//輸出:0.06
}
}
從上面的結果可以看出使用 string 類型的才能得到精確的計算結果。所有在計算金額時註意使用 string 類型創建對象。
2.2 減法(subtract)
import java.math.BigDecimal;
public class BigDecimalTest {
/**
* 測試減法 參數類型是double類型,計算還是不精確
*/
@Test
public void testSubtract1(){
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.subtract(b2));
//輸出:0.04000000000000000256739074444567449972964823246002197265625
}
/**
* 測試減法,參數類型是String類型,計算結果精確
*/
@Test
public void testSubtract2(){
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.subtract(b2));
//輸出:0.04
}
}
2.3 乘法(multiply)
import java.math.BigDecimal;
public class BigDecimalTest {
/**
* 測試乘法 參數類型是double類型,計算還是不精確
*/
@Test
public void testMultiply1(){
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.multiply(b2));
//輸出:0.0005000000000000000381639164714897566548413219067927041589808827754781955614304944646164585719816386699676513671875
}
/**
* 測試乘法,參數類型是String類型,計算結果精確
*/
@Test
public void testMultiply2(){
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.multiply(b2));
//輸出:0.0005
}
}
2.4 除法(divide)
2.4.1 除不盡,報錯
由於10/3除不盡,商是無限小數,所以報錯;
Non-terminating decimal expansion; no exact representable decimal result.
import java.math.BigDecimal;
public class BigDecimalTest {
/**
* 測試除法 參數類型是double類型
*/
@Test
public void testDivide1(){
BigDecimal b1 = new BigDecimal(0.1);
BigDecimal b2 = new BigDecimal(0.03);
System.out.println(b1.divide(b2));
//報錯 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
}
/**
* 測試除法,參數類型是String類型
*/
@Test
public void testDivide2(){
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.03");
System.out.println(b1.divide(b2));
//報錯 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
}
}
2.4.2 解決辦法
其實devide的函數定義如下:
BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode);
- scale為小數位數;
- roundingMode為小數模式;
小數模型有以下類型:
- ROUND_CEILING
如果 BigDecimal 是正的,則做 ROUND_UP 操作;如果為負,則做 ROUND_DOWN 操作。 - ROUND_DOWN
從不在捨棄(即截斷)的小數之前增加數字。 - ROUND_FLOOR
如果 BigDecimal 為正,則作 ROUND_UP ;如果為負,則作 ROUND_DOWN 。 - ROUND_HALF_DOWN
若捨棄部分> .5,則作 ROUND_UP;否則,作 ROUND_DOWN 。 - ROUND_HALF_EVEN
如果捨棄部分左邊的數字為奇數,則作 ROUND_HALF_UP ;如果它為偶數,則作 ROUND_HALF_DOWN 。 - ROUND_HALF_UP
若捨棄部分>=.5,則作 ROUND_UP ;否則,作 ROUND_DOWN 。 - ROUND_UNNECESSARY
該“偽舍入模式”實際是指明所要求的操作必須是精確的,,因此不需要舍入操作。 - ROUND_UP
總是在非 0 捨棄小數(即截斷)之前增加數字。
所有除法應該寫成以下形式;
BigDecimal num3 = num1.divide(num2,10,ROUND_HALF_DOWN);
import java.math.BigDecimal;
public class BigDecimalTest {
/**
* 測試除法 參數類型是double類型
*/
@Test
public void testDivide3(){
BigDecimal b1 = new BigDecimal(0.1);
BigDecimal b2 = new BigDecimal(0.03);
System.out.println(b1.divide(b2, 10, ROUND_HALF_DOWN));
//輸出:3.3333333333
}
/**
* 測試除法,參數類型是String類型
*/
@Test
public void testDivide4(){
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.03");
System.out.println(b1.divide(b2, 10, ROUND_HALF_DOWN));
//輸出:3.3333333333
}
3、小結
- 使用 string 類型創建 BigDecimal 對象來進行精確計算;
- 進行除法計算時,需要添加參數(scale)小數位數和(roundingMode)小數模式;避免出現除不盡報錯的現象;