Java中BigDecimal的使用

System.out.println(1.01 + 2.02);

 

你說能輸出什麼?3.03?實際上輸出的是3.0300000000000002。這是因爲不論是float 還是double都是浮點數,而計算機是二進制的,浮點數會失去一定的精確度。有沒有不失精度的辦法呢?這裏就要用到BigDecimal了.

java.math.BigDecimal。Java在java.math包中提供的API類BigDecimal。BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。

創建BigDecimal對象主要有兩種。


BigDecimal b1 = new BigDecimal("1.34");//1.34
BigDecimal b2 = BigDecimal.valueOf(1.34);//1.34

其中b1也可以寫成new BigDecimal(Double.toString(1.34)),可以直接new BigDecimal(1.34)嗎,也是可以的,只是會出現上述的精度問題。


BigDecimal one1 = new BigDecimal(1.34);//1.3400000000000000799360577730112709105014801025390625
BigDecimal two1 = new BigDecimal("1.34");//1.34

 

除了這兩種外,特殊的像0、1、10可以這樣寫。


BigDecimal zero = BigDecimal.ZERO;
BigDecimal one = BigDecimal.ONE;
BigDecimal ten = BigDecimal.TEN;

BigDecimal的加減乘除運算


public BigDecimal add(BigDecimal value);//加法
public BigDecimal subtract(BigDecimal value);//減法 
public BigDecimal multiply(BigDecimal value);//乘法
public BigDecimal divide(BigDecimal value);//除法

也可以照下面加法例子寫成一個util,另外三個都差不多就不展開了。

public static double add(double value1,double value2){
    BigDecimal b1 = new BigDecimal(Double.toString(value1));
    BigDecimal b2 = new BigDecimal(Double.toString(value2));
    return b1.add(b2).doubleValue();
}

BigDecimal的運算都沒有對原值進行操作,而是返回一個新的BigDecimal對象,這點可能有些小夥伴會搞錯要注意一下。

BigDecimal b1 =new BigDecimal("1.34");
System.out.println("b1: " + b1);
BigDecimal b2 =new BigDecimal("2.34");
b1.add(b2);
System.out.println("b1: " + b1);//b1並沒有變

BigDecimal的比較用的是BigDecimal的compareTo方法,將此 BigDecimal 與指定的 BigDecimal 比較。

根據此方法,值相等但具有不同標度的兩個BigDecimal對象(如,2.0 和 2.00)被認爲是相等的。

當此 BigDecimal 在數字上小於、等於或大於被比較對象時,返回 -1、0 或 1。

BigDecimal one = BigDecimal.valueOf(1);
BigDecimal two = BigDecimal.valueOf(2);
BigDecimal three = one.add(two);
int i1 = one.compareTo(two);//-1
int i2 = two.compareTo(two);//0
int i3 = three.compareTo(two);//1

*******************************

其實divide方法有可以傳三個參數

public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 
第一參數表示除數, 第二個參數表示小數點後保留位數,
第三個參數表示舍入模式,只有在作除法運算或四捨五入時纔用到舍入模式,有下面這幾種
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的方向舍入

另外: bigDecimal函數也可以使用setScale()函數,例如:


BigDecimal b = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_DOWN);
System.out.println(b);//2.22 直接去掉多餘的位數

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章