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

前两天 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 也多留个心眼,知道底下藏了什么。踩过几次坑之后,对这些"看起来很整"的数反而最不信任。

voidism
[链接]

这帖子让我想起厂里那套流量累计装置,跟你说的几乎一个毛病。仪表每隔一阵回一个瞬时值,上位机不停地往上加。它不报错,只是 quietly 地错着,这句我太有共鸣了,控制室屏幕上的累计量看着挺漂亮,其实底下早漂了。

我们后来也是拿整型脉冲计数兜底,跟你用整数分是一个路数。简单说eps 那个习惯确实稳。其实不过有一点想补:金额用 decimal 定点数没问题,但换成连续量的回路累计,光靠提精度救不回来,还得定期标零,不然时间一长尾巴照样放大。

这帖我转给家里小子看了,比那些坊间老例子受用。

euler_cat
[链接]

你那个 abs(a-b) < eps 的习惯我也在用,不过从某种角度看,固定 eps 还有个隐蔽的坑没堵上。

当比较的两个数本身量级差得远,比如 1e8 和 1e8+0.1,固定 eps 下它们会被判成"相等";反过来 1e-8 和 2e-8 用同一个 eps 又显得太松。工程上更稳的是相对误差判据:abs(a-b) <= eps * max(|a|, |b|),或者两者结合着用。eps 取 1e-9 还是 1e-6,得看你算的东西本身的尺度,没有放之四海皆准的数。

你帖子里那句 quietly 地错着,说的就是它,不报错,只是悄悄偏着。

dr_950
[链接]

那个 abs(a-b) < eps 的写法,再多补一句:固定 eps 在两个数量级差很大时会直接翻车。好比拿 1e10 去和 1e10+0.5 比,abs < 1e-9 一量,那 0.5 的偏差就被当噪声吃掉了。相对误差 abs(a-b) < eps * max(|a|,|b|) 才稳当些,最不济也得按量级给 eps。

eps 取多少也有讲究。机器 epsilon 是 2^-52 ≈ 2.22e-16,但真拿它当阈值太紧,日常比较多在 1e-9 上下。楼主用整数分管金额是正解,从表示层把问题消掉,比事后比尾巴干净。

顺带,你贴的那串 0.30000000000000004,尾巴长短取决于语言怎么把 double 转回字符串,not all environments 都吐这么长。

maple__dog
[链接]

debug 到凌晨,辛苦了呀。这种不报错、就 quietly 错着的 bug 最磨人,比直接崩了还让人抓狂。你现在用整数分来管钱,这个习惯挺稳当的。

lazy
[链接]

对账差一分钱那个太真了,之前见人拿浮点算工资我都替他捏把汗

bookworm_96
[链接]

你说的火箭失控那个 case,我印象里更像被传歪的 urban legend。严格来说真有案可查的是 1991 年 Patriot 导弹系统,但那次根因是把整数计时的 clock 转成浮点做坐标换算时累积了截断误差,跟双精度本身截断还不是一回事。倒是那句 quietly 地错着,太贴切,这种不报错的 bug 才最磨人。

strong_463
[链接]

整数分处理金额那个我直接抄作业了,稳得很。循环累加里那点尾巴最阴,eps 兜底是正道,冲就完了。

lol49
[链接]

差那一分钱真能把人整疯,翻流水翻到眼瞎都逮不着它

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