两个 double 做比较, 为什么加要个 1e-5 呢

2015-05-04 14:29:57 +08:00
 lyf362345
初学c++, 做练习题的时候跟答案对比, 发现有点不一样

练习题是:

描述
在北大校园里, 没有自行车, 上课办事会很不方便. 但实际上, 并非去办任何事情都是骑车快,
因为骑车总要找车、开锁、停车、锁车等, 这要耽误一些时间. 假设找到自行车,
开锁并骑上自行车的时间为27秒; 停车锁车的时间为23秒; 步行每秒行走1.2米,
骑车每秒行走3.0米. 请判断走不同的距离去办事, 是骑车快还是走路快.

输入
第一行为待处理的数据的数量n
其后每一行整数为一次办事要行走的距离,单位为米.

输出
对应每个整数,如果骑车快,输出一行"Bike";如果走路快,输出一行"Walk";如果一样快,输出一行"All".

样例输入
4
50
90
120
180

样例输出
Walk
Walk
Bike
Bike

我的代码
https://gist.github.com/fengqi/05b63a1264e52535b33b

答案里定义了个 `double delta = 1e-5` 然后比较的时候 再加上去, 这里有什么用呢
2023 次点击
所在节点    C
31 条回复
dslwind
2015-05-04 14:43:29 +08:00
大概是因为浮点数在计算机内部的存储和表示的问题,并不是所有浮点数都能“精确”的等于你想要的值。ps. biketime应该等于m/3.0+27+23。/3是整除……
acros
2015-05-04 14:45:38 +08:00
同楼上。
delta这个名字就表明了意思:误差范围。
zhicheng
2015-05-04 14:48:29 +08:00
如果两个 double 很接近,不能直接进行比较。细节太多,楼主多 Google 一下。
如果需要,我有一个封装好的可以直接拿来用。
https://github.com/zhicheng/fequal
cover
2015-05-04 14:50:45 +08:00
double的误差范围把。。比如你在做几何学运算的时候,两个角度相差 0.0001度的时候你就认为两个角度相等的意思
lyf362345
2015-05-04 15:00:42 +08:00
@dslwind 嗯 谢谢
lyf362345
2015-05-04 15:01:31 +08:00
@zhicheng 水很深呐, 我研究下你的代码
lyf362345
2015-05-04 15:02:00 +08:00
@cover 明白了, 非常感谢
lyf362345
2015-05-04 15:02:43 +08:00
@acros 恩恩 谢谢
msg7086
2015-05-04 15:11:47 +08:00
10进制的有限小数在2进制里不一定就是有限小数。
比如1.1(循环小数)+1.2(循环小数) 与 1.3(循环小数) 就不一定会相等,而是在最尾端可能会出现一个很小的误差。
lyf362345
2015-05-04 15:25:40 +08:00
@msg7086 嗯 谢谢啊
chai2010
2015-05-04 15:57:01 +08:00
Elethom
2015-05-04 16:14:54 +08:00
沒人吐槽應該是「both」麼?
comicfans44
2015-05-04 16:17:55 +08:00
浮点误差只有在比较相等的时候会用到,比如你判断
if(abs(walkTime-bikeTime)<delta){
cout<<"bike walk time equal"
}
可是现在你的逻辑是比较大小,当然是直接比较值,不明白答案为什么有delta。
如果说进制不同导致的计算误差用一个delta来补足,显然也是不合适的。
1e-5就不能用double准确表示(这本身就是一个十进制小数),怎么能假定加上一个不准确的delta就能让结果绝对准确?怎么能确定计算结果正好少了delta?如果需要绝对的准确性,那不应该加上delta,而是使用有理数进行计算。个人觉得这个delta是不合理的。
WKPlus
2015-05-04 16:23:55 +08:00
@comicfans44 对呀,不是浮点数用来判断是否相等的时候才需要引入一个delta的么?
Neveroldmilk
2015-05-04 17:08:17 +08:00
浮点数在计算机里不是精确存储的,会有误差,所以要设定阈值。
koykoi
2015-05-04 17:17:59 +08:00
比较大小要加什么阈值...
即使是 tolerance 设为 1e-5 也没什么道理
chai2010
2015-05-04 17:35:33 +08:00
fix typo: IEEE854 -> IEEE754
lyf362345
2015-05-04 20:02:43 +08:00
@Elethom both 那不就是都不加了么
lyf362345
2015-05-04 20:04:39 +08:00
@comicfans44
@WKPlus
@koykoi

几位的回答又让我不确定了...
CRVV
2015-05-04 23:38:41 +08:00
题目里说:如果一样快,输出一行"All"

我咋没在代码里看到"All"...
判断相等需要用阈值

而且这题直接和100比较,大于100骑车,小于100走路,关浮点数什么事

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/188337

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX