BigDecimal 正确使用

308 阅读2分钟

BigDecimal 的正确使用

BigDecimal 简介

BigDecimal 表示带有任意精度符号的十进制浮点数。BigDecimal 由任意精度整数非标度值(或称为有效数字)和32位整数标度(可正可负)组成。如果为零或正,则标度是该数的小数部分中的位数;如果为负,则该数的非标度值乘以10的负scale次幂是其绝对值。

关键点

  • 精度
    • setScale() 方法:用于设置小数位数,计算的时候用于保留给定的小数位数。

    注意和 precision 的区别。precision 指的是有效数字,包括整数和小数。例如 123.456,precision 是 6,scale 是 3。

  • 舍入模式
    • 总共 8 种不同的舍入模式。一般情况下,没有特殊要求,默认用 HALF_UP(四舍五入)模式。
      • UP:向远离零的方向舍入
      • DOWN:向靠近零的方向舍入
      • CEILING:向正无穷方向舍入
      • FLOOR:向负无穷方向舍入
      • HALF_UP:四舍五入
      • HALF_DOWN:五舍六入
      • HALF_EVEN:银行家舍入法,会根据数字末尾数字的奇偶性来确定舍入方式
      • UNNECESSARY:不需要舍入,如果出现非精确结果,则抛出ArithmeticException异常

    UP 和 CEILING 的区别:对于负数,UP 取较小值(远离 0 的方向),CEILING 取较大值(正无穷方向)。对于正数,UP 取较大值,CEILING 也是取较大值。例如:UP 模式下,10.1 将被舍入为11,而 -10.1 将被舍入为 -11。CEILING 模式下,10.1 将被舍入为 11,而 -10.1 将被舍入为 -10 。

最佳实践

  • 尽量用字符串代替数值类型(int、long、double之类的),避免数值类型本身的精度问题导致计算有误差。
  • 计算过程不要设置小数位数,直到最后结果输出的时候,才保留小数。可最大程度确保精度。
BigDecimal a = new BigDecimal("10.5"); 
BigDecimal b = new BigDecimal("7.25"); 
// 设置精度为:采用四舍五入方式保留两位小数。
BigDecimal c = a.divide(b, 2, RoundingMode.HALF_UP); 
System.out.println(c); // 输出1.45