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

年轻时候带学生做数值计算,有个娃跑来问我为什么累加结果死活对不上,嘴上还信誓旦旦说逻辑没问题。我瞄了一眼代码,好家伙,他在循环里拿 a == b 去判断两个浮点数是不是"相等"。

6说真的,0.1 加 0.2 在机器里压根不等于 0.3,这是 IEEE 754 那点精度误差闹的。循环里一比直接判 false,轻则结果离谱,重则卡成死循环出不来。正确姿势是取两者差的绝对值小于某个 epsilon,或者干脆换个思路别用浮点做精确相等判断。

这么基础的东西,答辩场上还有人踩。竞争才有进步,连浮点表示都没整明白,拿什么跟人卷。

spicyous
[链接]

你们计算机的坑真是开眼了,我连0.1+0.2都得掏手机按的人全程吃瓜。epsilon那招实在,差不离就当相等呗

void32
[链接]

补充一个坑。固定 epsilon 只挡住了最常见的情况,没解决量级差太大时的判断。两个量级差几个数量级的浮点摆一起,绝对值差可能永远大于你设的 epsilon,又被判成不相等。

更稳的是相对误差:|a-b| <= eps * max(|a|, |b|)。要更严格就上 ULP 比较(比最后几位有效位,ulp 是 unit in the last place,最小精度单位)。不过这些都没法根治——二进制浮点本来就连 0.1 都表示不精确。涉及钱、计数这类要精确相等的场景,别跟 float 死磕,直接上 decimal 类型或者整数分。其实

我大厂那会儿对账系统就有人拿 double 比金额,尾差一分钱对账永远不平,查了三天。选对数据类型比死磕精度省事。

savage_56
[链接]

学生嘴硬说逻辑没问题、实际卡在浮点相等那一幕,我能脑补出表情了 epsilon保命没毛病,可总有人连取多大eps都靠蒙。

legacy_2004
[链接]

0.1加0.2不等于0.3这个,我头回听说也愣了下,合着机器算账比人还会出岔子。

楼主说的取绝对值小于epsilon判等,路子是对的。不过有一点我想替那帮学生说句话——答辩场踩这种坑,真不算离谱。我年轻时候也觉得基础的东西必须门儿清才能上场,后来经历多了才明白,有些坑就是得亲手栽一次才刻进骨头里。你上来就把epsilon教给他们,不如让他们先撞一次墙,记得更牢。说实话

当然竞争归竞争,底子早晚得补齐,这没得说。你带的那届学生摔完这跤,下次估计再不会忘。

retro__824
[链接]

我年轻的时候也信过"算出来一样就是一样"。后来自己鼓捣点小东西,循环死活退不出去,对着屏幕愣了半天,才反应过来俩数在机器里其实隔着那么一丁点。

epsilon那套当然对,不过我后来觉得它也不是万能药。数特别大或者特别小的时候,定死一个阈值照样翻车,得看相对误差,或者干脆数数差了几个最小单位。都是摔过才记住的。

Genau. 这坑谁都绕不开。

canvas
[链接]

0.1加0.2不等于0.3,这事细想起来有种说不出的惆怅。我们总以为数字是世间最笃定的东西,一便是一,二便是二,像青石板上的刻痕,风吹雨打也不会变。可机器偏偏在最基础的算术里藏了一点暧昧,一点游移,像隔着一层起雾的玻璃看月亮,轮廓都在,却怎么也摸不到那层清辉。

你提到用epsilon去兜底,取差的绝对值小于某个极小的数便算作相等。这法子实用,可我总觉得它像极了人与人之间的相处。世上哪有严丝合缝的契合呢?非要拿一把分毫不差的尺子去量两颗心,最后多半也是判个false,各自走散。留一点容错的余地,承认微小的偏差本就是常态,事情才走得下去。

想起头一回进城,站在商场那架自动扶梯前,我愣是不敢迈脚。看着那些金属台阶不断咬合又分离,总觉得踩上去就会踏空。后来才明白,它并非静止的平地,而是一条流动的河,你得顺着它的节拍走。浮点数的世界大概也是这样,它不是铺好的青砖路,而是一条暗流涌动的河。拿着整数的规矩去丈量流水,自然会一脚踩空。

至于卷不卷的,我倒觉得,连这种细微处的敬畏心都没有,跑得越快反而越容易翻车。竞争固然催人向前,但走得急的人往往看不见脚下的裂缝。那些在答辩场上踩坑的孩子,未必是不够努力,可能只是太相信表面上的理所当然了。

git_649上回还跟我念叨,说写代码写到深夜,有时候会觉得屏幕上的字符像戏台上的水袖,甩出去就收不回来。curie54若是看到这篇帖子,估计又要翻出她那些压箱底的数值分析笔记了。

今晚昆明落了点小雨,听着雨声敲窗,忽然很想摆开棋盘下两局。象棋里的马走日象走田,规矩定得死死的,反倒让人觉得踏实。不知道你们平时写代码写得心里发毛的时候,都靠什么找回那点确定感?

chill__81
[链接]

0.1+0.2不等于0.3我第一次见的时候愣了半天。当年也帮人调过卡死的循环,全栽在==上,后来才懂拿绝对值比个epsilon就乖了哈哈

hugger
[链接]

那句"信誓旦旦说逻辑没问题"太有画面感了,我都能想象那孩子站你面前的样子。
没事的嗯嗯
其实这种坑踩过一次就再也不会忘,关键是得让他自己看见 0.1+0.2 到底输出了什么。我以前看人调程序,最管用的办法就是让他把中间值一个个打出来,眼见为实比讲十遍都强。

你后面说竞争才有进步,这点我特别认同。基础不扎实,后面再怎么努力都像在沙子上盖楼。不过也别太苛责那孩子,谁还不是从这种蠢错误里爬出来的呢。辛苦啦,带学生最磨的就是耐心。

bored_fox
[链接]

看到0.1+0.2那句直接笑出声 我连浮点啥样都没整明白还卷个啥 顺其自然得了

legacy83
[链接]

带新人时候我也撞见过,非跟个小数较劲,越较越拧巴。其实差那么一丁点就当相等呗,跟过日子一个理,太较真反倒出不来。这坑踩过一次就忘不掉了。

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