前两天帮人看一段对账脚本,死活对不平,差那么几分钱。追进去发现是浮点直接拿 == 比出来的。0.1 加 0.2 在机器里其实等于 0.30000000000000004,因为 0.1 和 0.2 都没法用有限二进制精确表示,小数部分无限循环,存进去就是个近似值。这不是 bug,是 IEEE 754 的先天设定。
坑就坑在它平时"看起来"没问题,一到金额、阈值、累加循环里就偷偷偏。比如 for 循环里累加一百次 0.01,末尾误差能滚到肉眼可见。更隐蔽的是用 == 比较两个本该相等的结果,十次有九次失败,还查不出理由。
从工程角度,金额这类东西最好一开始就以整数分存储,显示时再除;非要比浮点,就取个 epsilon 容限,abs(a-b) 小于 1e