BigDecimal如何使用?
1 BigDecimal简述
BigDecimal类是java.math包提供的用于准确计算的API类,用来对超过16位有效位的数进行精确的运算。虽然双精度浮点型变量double可以处理16位有效数,但在实际应用中可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字我们可以直接使用Float或Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。
BigDecimal所创建的是对象,因此我们不能使用+、-、*、/等算术运算符来实现加减乘除算数运算,而应当调用BigDecimal类对象的add、subtract、multiply或divide方法来进行算数运算!下面我们一起来尝试下。
2 BigDecimal算数运算
//1.测试基本的加减乘除 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));//保留2位小数,超出2位小数直接舍去
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 舍去小数取整
/** * 舍去小数 * @return */ public static String getIntegerStr(){ BigDecimal big = new BigDecimal(“0.245”); return big.setScale(0, BigDecimal.ROUND_DOWN).toString(); }