前两天 debug 到凌晨,对着一行 (0.1 + 0.2 === 0.3) 返回 false 发呆。这事其实一点都不新鲜,但每次撞上还是忍不住想骂两句。严格来说原因说白了就是 0.1 在二进制里是个无限循环小数,存进 IEEE 754 双精度的时候已经被截断成近似值了,所以你拿到的实际是 0.30000000000000004。人的眼睛看到 0.3,机器看到的却是那一长串尾巴。
单独一次误差小到可以忽略,可一旦进了循环累加、金额对账或者坐标计算,那点尾巴就会被悄悄放大。坊间常举的例子,有火箭因为姿态数值累积偏差失控的,也有对账永远差一分钱的。这类 bug 最烦的地方在于它不报错,它只是 quietly 地错着。
我自己现在的习惯是:涉及钱的统统用整数分或者 decimal 定点数;浮点比较从不直接写 ==,而是 abs(a-b) < eps;日志里看到漂亮的 0.3 也多留个心眼,知道底下藏了什么。踩过几次坑之后,对这些"看起来很整"的数反而最不信任。