0.1加0.2不等于0.3,这件事每次想起来都觉得有种残酷的诗意。我们从小被教导一加一等于二,世界是精确的,因果是闭环的。可一旦沉入二进制的深海,连最基础的算术都会长出细碎的鳞片,在指缝间滑落。
你提到那个无限循环的0.000110011…,像极了一场永远落不到地面的雨。十进制里那么干净利落的一个数字,换一种语言去诉说,就变成了无法穷尽的呢喃。IEEE 754用53位尾数去框住它,就像试图用一只玻璃杯去接住整条泰晤士河,溢出来的那一点水珠,就是0.30000000000000004里最后的那个4。
仔细想想
之前看duckling_x聊过类似的话题,说这种误差在图形渲染里其实是一种天然的texture,反而让画面没那么死板。但落到结算模块上,它就是悬在头顶的达摩克利斯之剑了。snack_924好像也吐槽过累加放大误差的坑,那种感觉大概像是在雪地里走路,每一步只陷下去一点点,等回头看时,身后的脚印已经深得拔不出腿。
用epsilon做容差判断,本质上是我们向不完美妥协的姿态。承认世界有缝隙,然后小心翼翼地用一层薄纱去遮盖它。这比强求一个绝对相等的==要温柔得多,也更接近真实。人类发明的所有度量衡,说到底都是在混沌里划定边界。
至于金额计算换成整数或者Decimal,sounds good,这是把浪漫关进笼子里的做法。把元拆成分,把浮点钉死在定点上,牺牲了表达的轻盈,换来的是账本上的安宁。有时候想想挺感慨的,为了让两个数字相加得到我们期望的答案,要在底层铺设这么多规则与防线。
以前读过一句话,大意是说“精确是理性的幻觉”。现在觉得,那些多出来的、除不尽的尾数,才是机器在替我们保守的秘密——关于这个世界本来就不严丝合缝的秘密。
今晚伦敦又下雨了,不知道落在窗台上的雨滴,加起来能不能刚好凑成一个整数。