乐趣区

Double精度丢失解决方案浅谈BigDecimal

  • 为什么金额要使用 BigDecimal 而不使用 Double?

在电商或者金融行业,看似很小的误差但是通过一番计算后会导致很大的误差,误差将演变为错误。错误将导致不能涨薪。
BigDecimal 类提供以下操作:算术、标度操作、舍入、比较、哈希算法和格式转换

1. double 精度丢失示例
 例 1:Double d1 = 1.0000001;
 Double d2 = 0.000002;
 // 理想输出 1.0000021, 实际输出 1.0000021000000001
 System.out.println(d1+d2);
 // 实际输出 1.0000021  理想输出 1.0000021
 System.out.println(new BigDecimal(d1.toString()).add(new     BigDecimal(d2.toString())));
 例 2:Double d3 = 11540d;
 Double d4 = 0.35;
 // 实际输出 4038.9999999999995 理想输出 4039
 System.out.println(d3*d4);
 // 实际输出 4039.000 理想输出 4039
 System.out.println(new BigDecimal(d3.toString()).multiply(new BigDecimal(d4.toString())));
2. BigDecimal 的基本使用
BigDecimal decimal =  new BigDecimal("1.3");
BigDecimal decimal1 =  new BigDecimal("3.32");
// 加
System.out.println(decimal.add(decimal1));
// 减
System.out.println(decimal1.subtract(decimal));
// 乘
System.out.println(decimal1.multiply(decimal));
// 除
System.out.println(decimal1.divide(decimal,2,BigDecimal.ROUND_CEILING));
3. BigDecimal 精度处理类型

BigDecimal 类使用户能完全控制舍入行为。如果未指定舍入模式,并且无法表示准确结果,则抛出一个异常;否则,通过向该操作提供适当的 MathContext 对象,可以对已选择的精度和舍入模式执行计算。在任何情况下,可以为舍入控制提供八种舍入模式。使用此类(例如,ROUND_HALF_UP)中的整数字段来表示舍入模式已过时;应改为使用 RoundingMode enum(例如,RoundingMode.HALF_UP)的枚举值。
八种舍入模式:

  CEILING 向正无限大方向舍入的舍入模式。DOWN 向零方向舍入的舍入模式。FLOOR 向负无限大方向舍入的舍入模式。HALF_DOWN  向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。HALF_EVEN 向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。HALF_UP  向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入 
  UNNECESSARY 用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。UP 远离零方向舍入的舍入模式。
退出移动版