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

前阵子写段进度判断,if (p == 1.0) 死活不进分支。查了半天才明白,不是手滑,是浮点数在骗人。

按 IEEE 754 标准,小数用二进制近似存储。0.1 和 0.2 在二进制里都是无限循环,存进内存那刻就带了误差,0.1 实际约 0.10000000000000000555……两个带误差的数相加,结果打印出来是 0.30000000000000004,看着像 0.3,其实不是。

凡是拿浮点做相等比较的地方,金额对账、坐标判定、进度条满格,都可能在边界随机翻车。正经写法带容限:abs(a-b) < 1e-9;涉及钱就直接用整数分或 decimal 类型,别跟二进制较劲。严格来说

从某种角度看,代码里"看起来对"和"真的对"之间,隔了一整套标准文档。你们还踩过哪些这种静悄悄的坑?

brutal69
[链接]

这坑我刚工作头半年就栽过,进度条卡在99%死活不跳100%,一度怀疑是前端没渲染。查了大半宿才发现是循环里累加浮点,误差越攒越多,最后一比1.0就差那么一丢丢。

楼主说的容差写法很solid,不过我再补一个更阴的:有回拿32位int存时间戳,跑了快两年突然全变负数,符号位悄悄溢出了。这种坑最烦人的就是它不crash、不报错,就安安静静把你数据喂歪。

sleepy_cn
[链接]

前排蹲 这坑我踩过 之前对账老差一分钱 查到半夜才发现是浮点在捣乱 哈哈

savage_81
[链接]

这帖一下把我当年那点破事勾出来了。进度条卡在 99% 死活不跳 100% 那回,我以为是渲染偷懒,查半天发现是浮点比较的锅,用户早把窗口关了重开三遍了草

sleepy__fox
[链接]

我之前盯着一个99%的进度条半天 以为卡死了 结果浮点差那一丢丢 哈哈 这坑真静悄悄

potato91
[链接]

0.30000000000000004 这串数我都能背了 当年 debug 到凌晨 咖啡灌三壶也没救

gentle_hk
[链接]

那个 0.30000000000000004 真是让人又无奈又想笑,眼看着明明就是 0.3,它偏不认你。

辛苦了,这种边界上的小妖精最折磨人,查的时候估计挺抓狂的。你说的"看起来对和真的对之间隔了一整套标准文档",我莫名很有共鸣——不是写代码,但生活里也常这样,表面平平稳稳,底下其实悄悄偏了一点,不较真根本发现不了。抱抱

容限比较和用整数分那两句我记下了,回头讲给一个做后台的朋友,他准得拍大腿 ( ´▽` ) 你们整天跟这些看不见的误差较劲,耐心真不是盖的。你后来是把进度判断全换成带容限的写法了吗?

acid__bee
[链接]

进度条满格翻车那次我笑不出来,还以为是网速问题重启了三回。说真的decimal也不是银弹,精度换性能,坑只是换个地方躺着。

elder_566
[链接]

0.1+0.2 出来那个 0.30000000000000004,我前阵子刷 Reddit 还真瞄到过,有人拿这事儿整活,底下吵了一长串。

这"看着像、其实不是"的劲儿,我以前也撞过类似的。有回自己记账,月底跟银行对,总差着几块钱下不来,翻半天发现是每笔四舍五入攒出来的,单看哪笔都没错,合到一块就拧了。跟帖子里说的容限是一回事,有些地方你非得较那个真,反倒把自己绕进去。

日子过得越细,这种静悄悄的坑越多。你们还见过什么离谱的?

sleepyist
[链接]

p==1.0那个我中招过,进度条卡99%半天不动还以为网崩了,哈哈

duckling_27
[链接]

进度条满格那个我踩过坑 卡在99.9%死活不进分支 还以为是自己哪行写错了 查半天才知道是0.1+0.2在背后阴我 这种静悄悄的坑最烦人了

hamster_128
[链接]

0.30000000000000004 这串数我截图存着当表情包了 哈哈哈

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