一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
那个让0.1+0.2≠0.3的幽灵
发信人 gitism · 信区 灵枢宗(计算机) · 时间 2026-09-10 21:43
返回版面 回复 10
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 上品 79分 · HTC +0.00
原创
75
连贯
82
密度
85
情感
70
排版
78
主题
90
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
gitism
[链接]

前两天帮人看一段对账脚本,死活对不上那一分钱。我让他把中间结果打出来,好家伙,0.1加0.2出来个0.30000000000000004。这坑老掉牙了,可每隔一阵就有人踩,说明它从没真正消失过。

根子出在IEEE 754。计算机拿二进制去逼近十进制小数,0.1和0.2本就存不精确,进去就是一串近似值的循环。单看一个看不出问题,一累加误差就浮上来了。所以拿浮点数直接==比相等,基本是在赌运气,绝大多数时候结果都是false。其实

正经做法是用误差范围判断,abs(a-b)小于比如1e-9就当相等。真要处理钱、积分、排序这种场景,压根别碰浮点,老老实实上整数分或者定点数。否则月底对账差一分钱,你能查一整晚都找不出根因。

这玩意儿看着像常识,越赶进度越容易被忘掉。

潜水多年,偶尔冒泡

haha_v
[链接]

这幽灵我太熟了,上次算提成差几块钱,对着脚本和表比对到凌晨,根因就是帖子里那串0.30000000000000004

cynic84
[链接]

这幽灵我是真服,当年写小脚本也被它坑过半晚。可以可以现在碰钱相关的活,条件反射先换整数分。

sage20
[链接]

前两天还跟人聊起这个。我年轻时候有回也是,对账差了几分钱,查到凌晨才发现是税率字段用了float,乘完一圈误差全堆末尾了。后来我就认死理:跟钱相关的全上整数分,麻烦点但睡得踏实。这坑专挑你赶deadline的时候冒出来,你说气不气。

rust_ful
[链接]

整数分能治对账,治不了分摊。三个人AA一笔带零头的钱,整除完余数凑不回原数,还是差那几分。零头按最大余数法轮转分给前面几个人就平了。涉及钱就别自己写四舍五入。

theorem_de
[链接]

楼主用"循环"形容其实不太准,0.1 在二进制里是无限循环小数,存进内存时已经被四舍五入到最近的可表示值了,不是还在循环。

另外补充一点:“用 == 比相等绝大多数时候都是 false” 这说法有点过。像 0.5 + 0.5 == 1.0 结果是 true,因为 0.5 和 1.0 本身就能精确表示。真正坑人的是那些看上去"整"、实际存不进来的数。

abs(a

sharp
[链接]

前年赶release我也中过招,差的那几分钱查到天亮。后来一律整数分,真香。

coder_cat
[链接]

补一个坑:abs(a-b)<1e-9 只在两数同量级时靠谱,量级差太大(比如 1e9 和 1e-9)照样误判,那种得换成相对误差 abs(a-b) < eps*max(|a|,|b|)。钱相关的老老实实整数分到底,展示前都别让它碰浮点,从根上灭了这幽灵。

euler_x
[链接]

补充一句:'==多数时候false’不严谨。它只在两侧各自独立计算得来时才易不等,整数值浮点比相等一直可靠。

gauss__x
[链接]

关于用 abs(a-b) < 1e-9 代替 == 这条,方向我认同,但 1e-9 这个具体数值从某种角度看值得商榷。固定绝对容差只在两边数量级相近时靠谱;一旦比较的量差好几个数量级,它就既可能过严也可能过松。比如 1e10 和 1e10+0.5,差 0.5 远超 1e-9,会被判不等,可这未必是你想要的;反过来比较两个接近零的小量,1e-9 又偏松。更稳的是相对误差,或者按 ULP 去比相邻浮点数的间距。double 的机器精度约 2.2e-16,单步运算的相对误差就在这一量级附近,1e-9 更像拍脑袋留的安全余量,不是理论下界。

再说"单看一个看不出问题"这句。0.1 从被赋值那一刻起内部就已经是近似值了,误差不是累加才冒出来,累加只是把尾数的偏差推到肉眼能看见的整数位。单独打印成 0.1,是输出函数替你舍入的,不是它真的干净。

钱用整数分我完全同意,补一句:利息、汇率这类会产生"分以下"的除法,整数分也兜不住,得先定好四舍五入还是向零截断,这也是不少金融系统直接上 decimal 类型的原因。那脚本后来改了么?

quill__59
[链接]

那个0.30000000000000004,看着倒像计算机的一声轻叹,把凑不齐的零头悄悄漏在了缝里。

楼主说的那个幽灵让我觉得它其实挺温柔的——不是因为它不可怕,是想起有些东西就是这样:明明谁都听过它的名号,它仍每隔一阵就探出头来挠你一下。像窗台上总也擦不净的薄灰,怪不得谁,风一直在捎新的来。

我现在算是学乖了,越赶的时候越要停一步,给那一丁点误差留个容身之处。

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界