场景说明
在进行金额表示、金额计算时,不能使用double,float,要使用对精度支持更好的BigDecimal,所以,很多支付、电商、金融等业务中,BigDecimal的使用非常频繁。
注意事项
1.BigDecimal 不能使用equals 方法做等值比较
2.BigDecimal 使用double 初始化时存在精度风险
对equal的解释
BigDecimal 的 equal 比较了两部分:值(value)和精度值(scale)
BigDecimal 有四个构造方法:
BigDecimal(int)
BigDecimal(double)
BigDecimal(long)
BigDecimal(String)
1 BigDecimal(int) 和 BigDecimal(long) ,因为是整数,所以精度是0,对应源码
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
public BigDecimal(long val) {
this.intCompact = val;
this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
this.scale = 0;
}
2 BigDecimal(double)
由于double 自身表示的是一个近似值,当使用new BigDecimal(0.1)的时候,创建出来的值并不是0.1
System.out.println(new BigDecimal(0.1));
0.1000000000000000055511151231257827021181583404541015625
new BigDecimal(0.10) 也同理。
BigDecimal(1.0) 和 BigDecimal(1.00) 这样形式的,本质上是整数,创建出来的数字的精度是0
System.out.println(new BigDecimal(1.0));
System.out.println(new BigDecimal(1.00));
1
1
3 举例
BigDecimal bigDecimal1 = new BigDecimal(1);
BigDecimal bigDecimal2 = new BigDecimal(1);
System.out.println(bigDecimal1.equals(bigDecimal2));
BigDecimal bigDecimal3 = new BigDecimal(1);
BigDecimal bigDecimal4 = new BigDecimal(1.0);
System.out.println(bigDecimal3.equals(bigDecimal4));
BigDecimal bigDecimal5 = new BigDecimal("1");
BigDecimal bigDecimal6 = new BigDecimal("1.0");
System.out.println(bigDecimal5.equals(bigDecimal6));
结果:
true
true
false
如何比较BigDecimal 呢
BigDecimal bx = new BigDecimal("1");
BigDecimal by = new BigDecimal("1.0000");
System.out.println(bx.compareTo(by));
结果:
0
最后,使用说明
1 BigDecimal 的等值比较应该使用compareTo 而不是 equal 方法
- equals 会比较值和精度,而compareTo 则会忽略精度
2 禁止使用构造方法BigDecimal(double) 的方式把double 值转化成BigDecimal 对象
- BigDecimal(double) 会存在精度损失风险,可能会导致业务异常;
- 优先推荐使用String 的构造方法 或使用BigDecimal 的 valueOf() 方法,valueOf() 方法内部其实执行了Double 的toString()
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b1 = BigDecimal.valueOf(0.1);
网友评论