BigDecimal能夠理解爲一個浮點數, 其大小可任意指定並且精度準確, 故平常用在金額,利息等金錢相關的字段上,因最近使用較多,故記錄一下,給你們參考一下,避免其中的問題.java
// 使用字符串,不會出現精度損失 (推薦)
// 結果: 0.1
BigDecimal bigDecimal = new BigDecimal("0.1");
// 使用int整數,會出現精度損失
// 結果: 0.1000000000000000055511151231257827021181583404541015625
BigDecimal bigDecimal2 = new BigDecimal(0.1);
複製代碼
ps: String和BigDecimal互相轉換數組
// 字符串轉BigDecimal
String str = "100.01";
BigDecimal bigDecimal = new BigDecimal(str);
// BigDecimal轉字符串
BigDecimal big = new BigDecimal("13.14");
String string = big.toString();
String string2 = String.valueOf(big);
複製代碼
scale是BigDecimal的一個成員屬性,final關鍵字修飾,不能修改,表示小數位數.markdown
BigDecimal d1 = new BigDecimal("12.10");
BigDecimal d2 = new BigDecimal("123.1000");
BigDecimal d3 = new BigDecimal("1234500");
// 小數位 2
System.out.println(d1.scale());
// 小數位 4
System.out.println(d2.scale());
` // 小數位 0
System.out.println(d3.scale());
複製代碼
BigDecimal中stripTrailingZeros()方法,能夠轉換成一個新的BigDecimal,去掉了末尾的數字0.ide
BigDecimal d1 = new BigDecimal("123.4500");
BigDecimal d2 = d1.stripTrailingZeros();
// 小數位 4
System.out.println(d1.scale());
// 小數位 2,由於去掉了00
System.out.println(d2.scale());
BigDecimal d3 = new BigDecimal("1234500");
BigDecimal d4 = d3.stripTrailingZeros();
// 小數位 0
System.out.println(d3.scale());
// 小數位 -2
System.out.println(d4.scale());
複製代碼
總結:spa
1 一個 BigDecimal對象的scale()
方法返回負數, 如-2,表示這個數是整數,結尾有2個0code
2 一個BigDecimal對象結尾沒有0,再調用stripTrailingZeros()方法,獲得的結果不變.orm
類型 | 說明 |
---|---|
ROUND_DOWN | 去掉多餘的位數 |
ROUND_UP | 向前進位處理 |
ROUND_CEILING | 若是是正數,就是ROUND_UP ; 若是是負數,就是ROUND_DOWN |
ROUND_FLOOR | 若是是正數,就是ROUND_DOWN ; 若是是負數,就是ROUND_UP |
ROUND_HALF_UP | 四捨五入,大於等於5,就進位(>=5) |
ROUND_HALF_DOWN | 四捨五入,大於5,才進位(>5) |
ROUND_HALF_EVEN | 若是捨棄部分左邊的數字爲偶數,爲HALF_DOWN ; 若是捨棄部分左邊的數字爲奇數,爲ROUND_HALF_UP |
ROUND_UNNECESSARY | 斷言請求的操做具備精確的結果,所以不須要舍入 |
// 關於模式,舊的和新的描述不同,但效果一致
// 直接去掉多餘的位數
// 1 RoundingMode.DOWN == BigDecimal.ROUND_DOWN
BigDecimal b = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_DOWN);
System.out.println(b);
// 跟上面相反,進位處理
// 2 RoundingMode.UP == BigDecimal.ROUND_UP
BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_UP);
System.out.println(c);
// 若是是正數,至關於BigDecimal.ROUND_UP ; 若是是負數,至關於BigDecimal.ROUND_DOWN
// 3 RoundingMode.CEILING == BigDecimal.ROUND_CEILING
BigDecimal f = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_CEILING);
System.out.println(f);
BigDecimal g = new BigDecimal("-2.225667").setScale(2, BigDecimal.ROUND_CEILING);
System.out.println(g);
// 若是是正數,至關於BigDecimal.ROUND_DOWN ; 若是是負數,至關於BigDecimal.ROUND_HALF_UP
// 4 RoundingMode.FLOOR == BigDecimal.ROUND_FLOOR
BigDecimal h = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_FLOOR);
System.out.println(h);
BigDecimal i = new BigDecimal("-2.224667").setScale(2, BigDecimal.ROUND_FLOOR);
System.out.println(i);
// 四捨五入(若捨棄部分>=.5,就進位)
// 5 RoundingMode.HALF_UP == BigDecimal.ROUND_HALF_UP
BigDecimal d = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("ROUND_HALF_UP" + d);
// 四捨五入(若捨棄部分>.5,就進位)
// 6 RoundingMode.HALF_DOWN == BigDecimal.ROUND_HALF_DOWN
BigDecimal e = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_DOWN);
System.out.println("ROUND_HALF_DOWN" + e);
// 若是捨棄部分左邊的數字爲偶數,則做 ROUND_HALF_DOWN ; 若是捨棄部分左邊的數字爲奇數,則做 ROUND_HALF_UP
// 7 RoundingMode.HALF_EVEN == BigDecimal.ROUND_HALF_EVEN
BigDecimal j = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_EVEN);
System.out.println(j);
BigDecimal k = new BigDecimal("2.215").setScale(2, BigDecimal.ROUND_HALF_EVEN);
System.out.println(k);
// 斷言請求的操做具備精確的結果,所以不須要舍入。若是對得到精確結果的操做指定此舍入模式,則拋出ArithmeticException。
// 8 RoundingMode.UNNECESSARY == BigDecimal.ROUND_UNNECESSARY
BigDecimal bigDecimal = new BigDecimal("2.215").setScale(3, BigDecimal.ROUND_UNNECESSARY);
System.out.println(bigDecimal);
複製代碼
計算加、減、乘,不會有精度丟失,除法運算時,若是存在沒法除盡,須要指定精度.對象
BigDecimal n = new BigDecimal("123.456");
BigDecimal m = new BigDecimal("23.456789");
// 加法
System.out.println(n.add(m));
// 減法
System.out.println(n.subtract(m));
// 乘法
System.out.println(n.multiply(m));
// 除法
// 報錯:ArithmeticException,由於除不盡
// System.out.println(n.divide(m));
// 保留10位小數並四捨五入
System.out.println(n.divide(m, 10, RoundingMode.HALF_UP));
複製代碼
返回的數組包含兩個BigDecimal
,分別是商和餘數,其中商老是整數,餘數不會大於除數.ip
BigDecimal n = new BigDecimal("12.75");
BigDecimal m = new BigDecimal("0.15");
BigDecimal[] dr = n.divideAndRemainder(m);
if (dr[1].signum() == 0) {
System.out.println("n是m的整數倍");
}
System.out.println(dr[0]);
System.out.println(dr[1]);
複製代碼
比較兩個BigDecimal, 不要使用==equals()方法==,由於==equals()方法==既要求兩個BigDecimal值相等,還要求兩個對象的小數位相等.ci
BigDecimal d1 = new BigDecimal("123.1");
BigDecimal d2 = new BigDecimal("123.10");
// false,由於scale不一樣
System.out.println(d1.equals(d2));
// true,由於d2去除尾部0後scale變爲2
System.out.println(d1.equals(d2.stripTrailingZeros()));
複製代碼
BigDecimal的比較, 須要使用==compareTo()方法==, 根據兩個對象比較的結果返回負數,0和正數
// 相等 0
BigDecimal d1 = new BigDecimal("123.1");
BigDecimal d2 = new BigDecimal("123.1");
System.out.println(d1.compareTo(d2));
// 大於 1
BigDecimal d3 = new BigDecimal("123.2");
BigDecimal d4 = new BigDecimal("123.1");
System.out.println(d3.compareTo(d4));
// 小於 -1
System.out.println(d4.compareTo(d3));
複製代碼
在使用中,儘可能靠近0去作判斷比較, 據說可能會出現比較結果爲小數的狀況, 可是博主暫時沒有發現.
注意:
老是使用compareTo()
比較兩個BigDecimal的值,不要使用equals()
!