为什么不能使用浮点数表示金额

97 阅读1分钟

十进制转二进制

十进制整数转二进制,除2取余,直至商小于1,顺序排列余数

例如:127的二进制计算:

127 / 2 = 631   
 63 / 2 = 311  
 31 / 2 = 151  
 15 / 2 =  71  
  7 / 2 =  31  
  3 / 2 =  11  
  1 / 2 =  01 
  
  结果: 127的二进制1111111 (7个1)

十进制小数转二进制,乘2取整,直至乘积小数部分为0,顺序排列

例如:0.625的二进制计算:

0.625 * 2 = 1.25 取整 1
0.25  * 2 = 0.5  取整 0 
0.5   * 2 = 1.0  取整 1
  
  结果: 0.625的二进制0.101

不是所有小数都能用二进制表示,比如:0.1

例如:0.1的二进制计算:

0.1 * 2 = 0.2 取整 0
0.2 * 2 = 0.4 取整 0 
0.4 * 2 = 0.8 取整 0 
0.8 * 2 = 1.6 取整 1 
0.6 * 2 = 1.2 取整 1 
...
  
  结果: 0.1的二进制取值无穷无尽,即0.00011...

总结

对于二进制取值无穷无尽的小数,只能使用固定的有效位数表示,故会损失精度

扩展

float 固定32位,单精度浮点数 double 固定64位,双精度浮点数 均存在损失精度情况,因为位数固定,无法表示精度超过位数的小数

可以使用BigDecimal进行精度计算

参考资料

Hollis 大神的《2023全新Java面试宝典课程,八股文学习资料》