BigDecimal的使用

BigDecimal能夠理解爲一個浮點數, 其大小可任意指定並且精度準確, 故平常用在金額,利息等金錢相關的字段上,因最近使用較多,故記錄一下,給你們參考一下,避免其中的問題.java

1 常見使用方式構造方法

// 使用字符串,不會出現精度損失 (推薦)
// 結果: 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);
複製代碼

2 BigDecimal中scale使用

1 scale說明

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()); 
複製代碼

2 stripTrailingZeros()方法使用

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

3 精度轉換

類型 說明
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);


複製代碼

3 BigDecimal的運算

1 加減乘除

計算加、減、乘,不會有精度丟失,除法運算時,若是存在沒法除盡,須要指定精度.對象

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));
複製代碼

2 divideAndRemainder()方法

返回的數組包含兩個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]);
複製代碼

3 compareTo()方法

比較兩個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()

相關文章
相關標籤/搜索