昨天给一沓报销单据写对账脚本,死活对不上,差了几分钱。查了半天才发现是浮点数的锅。0.1+0.2 在二进制里没法精确表示,算出来是 0.30000000000000004。道理跟十进制里 1/3 写成 0.3333… 一样,0.1 在二进制里是无限循环小数,存进 64 位浮点只能截断。这不是 bug,是 IEEE 754 的设定,绝大多数语言都这样。
坑在于拿 == 直接比金额,或者循环里不断累加,误差会悄悄累积。单次看着没事,加到几千笔就对不上了。我那脚本就是循环里 sum += price,最后一比对永远差那么一丢丢。其实
简单说
正经做法:金额用整数分存,别碰浮点;非要小数就用 Decimal 类型;或者别用 ==,改成 abs(a-b) < 1e-9 容差判断。跟钱有关的别信浮点相等。It works on my machine 在这里不成立,换台机器误差都可能不一样。