BigDecimal類是java.math包提供的用於準確計算的API類,用來對超過16位有效位的數進行精確的運算。雖然雙精度浮點型變量double可以處理16位有效數,但在實際應用中可能需要對更大或者更小的數進行運算和處理。一般情況下,對於那些不需要準確計算精度的數字我們可以直接使用Float或Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。如果我們需要精確計算的結果,則必須使用BigDecimal類來操作。
BigDecimal所創建的是對象,因此我們不能使用+、-、*、/等算術運算符來實現加減乘除算數運算,而應當調用BigDecimal類對象的add、subtract、multiply或divide方法來進行算數運算!下面我們一起來嘗試下。
2 BigDecimal算數運算log.info("a + b={}", new BigDecimal("5.5").add(new BigDecimal("4.1"))); log.info("a - b={}", new BigDecimal("10.6").subtract(new BigDecimal("3.8"))); log.info("a * b={}", new BigDecimal("12.1").multiply(new BigDecimal("0.13")));
log.info("a ÷ b={}", new BigDecimal("12.1").divide(new BigDecimal("3.2"), 2, BigDecimal.ROUND_DOWN));
3 Rounding mode(捨入模式)Rounding mode是Bigdecimal類對象捨入模式。其提供了8種捨入模式,使用時按需選擇即可!開發者常常不清楚各種捨入模式的作用或區別,博主就給大家詳細講解下!
3.1 RoundingMode.DOWN粗暴截斷捨棄多餘位(捨去小數第3位及其後面小數),不考慮任何進位舍位操作。等價於BigDecimal.ROUND_DOWN。
1.331 ---> 1.33
1.2199 ---> 1.21
1.308 ---> 1.30
log.info("RoundingMode.DOWN={}", new BigDecimal("1.331").setScale(2, RoundingMode.DOWN)); log.info("RoundingMode.DOWN={}", new BigDecimal("1.2199").setScale(2, RoundingMode.DOWN)); log.info("RoundingMode.DOWN={}", new BigDecimal("1.308").setScale(2, RoundingMode.DOWN));
3.2 RoundingMode.UP小數第3位粗暴進位,朝遠離數軸的方向進位。正數+1,負數-1。等價於BigDecimal.ROUND_UP。
3.3333 ---> 3.34
1.7397 ---> 1.74
-2.8699 ---> -2.87
-2.1096 ---> -2.11
log.info("RoundingMode.UP={}", new BigDecimal("3.3333").setScale(2, RoundingMode.UP)); log.info("RoundingMode.UP={}", new BigDecimal("1.7397").setScale(2, RoundingMode.UP)); log.info("RoundingMode.UP={}", new BigDecimal("-2.8699").setScale(2, RoundingMode.UP)); log.info("RoundingMode.UP={}", new BigDecimal("-2.1096").setScale(2, RoundingMode.UP));3.3 RoundingMode.CEILING精度保留的最後一位,朝數軸正方向round。正數時等價於UP,負數時等價於DOWN。等價於BigDecimal.ROUND_CEILING
3.2333 ---> 3.24
1.7777 ---> 1.78
-4.5689 ---> -4.56
-1.1076 ---> -1.10
log.info("RoundingMode.CEILING={}", new BigDecimal("3.2333").setScale(2, RoundingMode.CEILING)); log.info("RoundingMode.CEILING={}", new BigDecimal("1.7777").setScale(2, RoundingMode.CEILING)); log.info("RoundingMode.CEILING={}", new BigDecimal("-4.5689").setScale(2, RoundingMode.CEILING)); log.info("RoundingMode.CEILING={}", new BigDecimal("-1.1076").setScale(2, RoundingMode.CEILING));3.4 RoundingMode.FLOOR與CEILING 相反,在精度最後一位,朝數軸負方向round。正數時等價於DOWN,負數時等價於UP。等價於BigDecimal.ROUND_FLOOR。
3.2333 ---> 3.23
1.7777 ---> 1.77
-4.5689 ---> -4.57
-1.1076 ---> -1.11
-1.1016 ---> -1.11
log.info("RoundingMode.FLOOR={}", new BigDecimal("3.2333").setScale(2, RoundingMode.FLOOR)); log.info("RoundingMode.FLOOR={}", new BigDecimal("1.7777").setScale(2, RoundingMode.FLOOR)); log.info("RoundingMode.FLOOR={}", new BigDecimal("-4.5689").setScale(2, RoundingMode.FLOOR)); log.info("RoundingMode.FLOOR={}", new BigDecimal("-1.1076").setScale(2, RoundingMode.FLOOR)); log.info("RoundingMode.FLOOR={}", new BigDecimal("-1.1016").setScale(2, RoundingMode.FLOOR));3.5 RoundingMode.HALF_UP四捨五入。等價於BigDecimal.ROUND_HALF_UP。
1.331 ---> 1.33
1.2199 ---> 1.22
-4.5689 ---> -4.57
-1.1076 ---> -1.11
-1.1016 ---> -1.10
-2.555 ---> -2.56
log.info("RoundingMode.HALF_UP={}", new BigDecimal("1.331").setScale(2, RoundingMode.HALF_UP)); log.info("RoundingMode.HALF_UP={}", new BigDecimal("1.2199").setScale(2, RoundingMode.HALF_UP)); log.info("RoundingMode.HALF_UP={}", new BigDecimal("-4.5689").setScale(2, RoundingMode.HALF_UP)); log.info("RoundingMode.HALF_UP={}", new BigDecimal("-1.1076").setScale(2, RoundingMode.HALF_UP)); log.info("RoundingMode.HALF_UP={}", new BigDecimal("-1.1016").setScale(2, RoundingMode.HALF_UP)); log.info("RoundingMode.HALF_UP={}", new BigDecimal("-2.555").setScale(2, RoundingMode.HALF_UP));3.6 RoundingMode.HALF_DOWN五舍六入。等價於BigDecimal.ROUND_HALF_DOWN。
1.331 ---> 1.33
1.2199 ---> 1.22
2.555 ---> 2.55
2.556 ---> 2.56
-4.5689 ---> -4.57
-1.1076 ---> -1.11
-1.1016 ---> -1.10
-2.555 ---> -2.55
-2.556 ---> -2.56
log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("1.331").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("1.2199").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("2.555").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("2.556").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("-4.5689").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("-1.1076").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("-1.1016").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("-2.555").setScale(2, RoundingMode.HALF_DOWN)); log.info("RoundingMode.HALF_DOWN={}", new BigDecimal("-2.556").setScale(2, RoundingMode.HALF_DOWN));3.7 RoundingMode.HALF_EVEN當捨入位非5時,四捨六入。當捨入位為5時,看捨入位前一位,即保留的最後一位,當其為奇數時進位,否則舍位。等價於 BigDecimal.ROUND_HALF_EVEN。
-2.555 ---> -2.56
-2.545 ---> -2.54
2.555 ---> 2.56
2.545 ---> 2.54
log.info("RoundingMode.HALF_EVEN={}", new BigDecimal("-2.555").setScale(2, RoundingMode.HALF_EVEN)); log.info("RoundingMode.HALF_EVEN={}", new BigDecimal("-2.545").setScale(2, RoundingMode.HALF_EVEN)); log.info("RoundingMode.HALF_EVEN={}", new BigDecimal("2.555").setScale(2, RoundingMode.HALF_EVEN)); log.info("RoundingMode.HALF_EVEN={}", new BigDecimal("2.545").setScale(2, RoundingMode.HALF_EVEN));3.8 RoundingMode.UNNECESSARY認為傳入的數據一定滿足設置的小數模式,如果不滿足,則拋出ArithmeticException異常。等價於BigDecimal.ROUND_UNNECESSARY。
2.54 ---> 2.54
2.540 ---> 2.54
2.541 ---> 拋ArithmeticException異常
log.info("RoundingMode.UNNECESSARY={}", new BigDecimal("2.54").setScale(2, RoundingMode.UNNECESSARY)); log.info("RoundingMode.UNNECESSARY={}", new BigDecimal("2.540").setScale(2, RoundingMode.UNNECESSARY)); log.info("RoundingMode.UNNECESSARY={}", new BigDecimal("2.541").setScale(2, RoundingMode.UNNECESSARY));4 常見示例4.1 捨去小數取整public static String getIntegerStr(){ BigDecimal big = new BigDecimal("0.245"); return big.setScale(0, BigDecimal.ROUND_DOWN).toString(); }如果你有疑問或需要技術支持,關注公眾號聯繫我吧~