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 直接去掉多餘的位數