前言: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 加減乘除
-
加法:add
-
減法:subtract
- 乘法:multiply
- 除法: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 '數值',
--------------如果大家喜歡我的博客,可以點擊左上角的關注哦。