前两天写了段对账的小脚本,算出来总和死活跟总分录对不上,差了几分钱。查了半天才定位到是浮点数的锅。
0.1加0.2在机器里结果其实是0.30000000000000004。原因不复杂:十进制的0.1、0.2转成二进制是无限循环小数,塞进double只能截断近似,误差从存储那一刻就埋下了。所以千万别用==去判断两个小数相等,表面一样底下早就差出一截。
更隐蔽的是循环累加,每加一次误差叠一点,跑几千遍之后偏差就肉眼可见,金额和统计类活儿最容易悄悄算错。我现在要么用整数,金额直接以分存;要么比较时放个容差,abs(a-b)<1e-9就算相等;要精度就老老实实上Decimal。
踩过一次就长记性了,浮点不是数学,只是近似。