1 为什么浮点数运算有精度丢失风险
- 原因:计算机在存储浮点数时,指数和尾数能占用的bit位是固定的,十进制小数在转二进制小数时乘2取整,直到不存在小数为止,如果在运算时超过尾数限制的bit位长度,就会被截断,所以就导致小数精度发生损失
- 解决方法:定义一个误差范围;或使用decimal
2 底层原理
- 十进制整数在转化为二进制数时不会有精度问题,所以将十进制小数扩大N被让它在整数维度上进行计算(BigInteger类型),并记录小数点位置即可;
- BigDecimal进行运算时分解为两部分,BigInteger间的计算,以及小数点位置scale的更新;例如加法运算时,先按整数计算,然后更新小数点的位置为两者小数位小的那个值
3 BigDecimal使用时避雷点
- 不要使用BigDecimal(double),存在精度损失风险,因为实际存储的值是double数值的二进制表示,可能会有精度损失
- 使用除法注意事项:使用roundingMode指明结果的保留规则,否则遇到无限循环小数时,会报错
- BigDecimal等值比较时,使用CompareTo(),而不是equals(),因为equals会比较精度,而compareTo会忽略精度,那些无实际意义的0会自动忽略