帖子里说 double 是"截断近似",这个我得较较真。IEEE 754 默认的舍入模式是向偶数舍入(round to nearest, ties to even),不是截断。0.1 存进 double 时,实际落到了 0.10000000000000000555……这个最接近的可表示值,比真值略大;0.2 同理。所以 0.1+0.2 出来 0.30000000000000004,本质是两次"向最近值舍入"叠加的结果,而不是把尾数砍掉。截断只是众多舍入策略里的一种,现实里默认走的不是它。
另一个想补的是容差那句。"abs(a-b)<1e-9 就算相等"在金额这种量纲固定的场景没问题,但当成通用经验其实有点悬。1e-9 是个绝对阈值,它不关心你比的两个数本身有多大:两边都是上亿的量,差个 1e-9 根本测不出该测的偏差;反过来比两个极小量,1e-9 又太松。更稳的是相对容差,或者像 Python 的 math.isclose 那样把 rel_tol 和 abs_tol 组合着用。你按分存整数已经是治本了,这条主要给以后跨量纲比较提个醒。
顺带说一句,Decimal 也不是免死金牌。它能精确表示 0.1、0.2,但 1/3 这种除法结果在 Decimal 里照样是无限小数,默认 28 位有效数字也会截断,拿 == 去比除法结果照样翻车。所以"用 Decimal 就别用 ==“其实该改成"不管什么类型,只要涉及除法或非终止结果就别用 ==”。其实
你那脚本后来是全改成按分存整数了,还是 Decimal 混着用?我现在但凡碰金额也一律整数,省心多了。