Redian新闻
>
浮点数运算等于0的问题
avatar
浮点数运算等于0的问题# Programming - 葵花宝典
V*t
1
今天太晚了,少写点。。
斯台方诺 纳波里民歌(一)
http://www.amazon.com/Giuseppe-Stefano-Sings-Neapolitan-Songs/dp/B000003XK0/ref=pd_bxgy_m_img_b
斯台方诺曾被称为“第一男高音”,是很多后来成名歌唱家最最崇拜的偶像。然而他的
嗓子却因为过度使用,过早的毁掉,成为声乐史上失败的一例。但是,斯台方诺的激情
,还有他美妙动人的歌声,给所有爱乐者都留下了不可磨灭的深刻印象。
这张盘是斯台方诺最出名的一场CD(卡雷拉斯自传里也提到这张盘,说他听了之后是如
何的如痴如醉),听的时候仿佛就能感到地中海灿烂的阳光。特别推荐《负心人》,是
我听过最好的版本。
avatar
i*r
2
我记得氢弹应该用原子弹来引爆,由原子弹爆炸时产生的高温来点燃热核原料而进行聚
变反应。怎么一个妇道人家口里面喊着sob用砖头拍几下就爆了。
avatar
s*k
3
碰到一个非常困惑的问题
比如有一个浮点正数数组a[],
然后我通过一个for循环找到这个数组里面最小的数,
赋值为b,
然后for循环把a里每个数都减去这个b,
得到新的a.
那么这a[]里面一定有一个为0.0
我用 a[i]==0.0 来找这个index i,
发现有时候找不到,原来有时候减完b后
的a[]本来应该为0.0的那个数是一个非常小的数,而不等于0.0
请问有经验的人说说这个是我的程序出错呢,
还是新的那个a[]里最小的那个数有可能不等于0
浮点数运算难道 会有 a-a 不等于0的情况吗?
avatar
k*a
4
砸的不是氢弹,是热核弹头,所谓plutonium core。
不过理论上热核弹头也需要强大的压缩才能产生反应,敲两下估计够呛。

【在 i******r 的大作中提到】
: 我记得氢弹应该用原子弹来引爆,由原子弹爆炸时产生的高温来点燃热核原料而进行聚
: 变反应。怎么一个妇道人家口里面喊着sob用砖头拍几下就爆了。

avatar
b*j
5
应该没有问题,a - a应该是0
除非你b和a的类型不一致,或者中间又做了其他运算

【在 s*****k 的大作中提到】
: 碰到一个非常困惑的问题
: 比如有一个浮点正数数组a[],
: 然后我通过一个for循环找到这个数组里面最小的数,
: 赋值为b,
: 然后for循环把a里每个数都减去这个b,
: 得到新的a.
: 那么这a[]里面一定有一个为0.0
: 我用 a[i]==0.0 来找这个index i,
: 发现有时候找不到,原来有时候减完b后
: 的a[]本来应该为0.0的那个数是一个非常小的数,而不等于0.0

avatar
t*g
6
敲的是引爆装置的电子系统, 造成短路, 引起爆炸
avatar
z*e
7
if( abs(a-b) < numeric_limits::epsilon() );
or
if( abs(a-b) < c*numeric_limits::epsilon() );//c=2,5,10.etc,....
avatar
Z*e
8
不要较真吧。。。我觉得把氢弹的core挖出来背着在岛上乱转本来就不太靠谱...

【在 i******r 的大作中提到】
: 我记得氢弹应该用原子弹来引爆,由原子弹爆炸时产生的高温来点燃热核原料而进行聚
: 变反应。怎么一个妇道人家口里面喊着sob用砖头拍几下就爆了。

avatar
U*d
9
浮点判零是一个经典问题啊,一定不能a==0.0,应该用类似于if(a<10e-20 && a>-10e-
20)的条件判断。
至于原因嘛……嘿嘿,不说。
avatar
c*c
10
改装过了,撞击就可以引爆

【在 i******r 的大作中提到】
: 我记得氢弹应该用原子弹来引爆,由原子弹爆炸时产生的高温来点燃热核原料而进行聚
: 变反应。怎么一个妇道人家口里面喊着sob用砖头拍几下就爆了。

avatar
a*d
11
assuming fn is the min of f[0-m], then fn-fn=0, and others fi - fn >= 0. I
don't see why the n'th subtraction isn't 0.
paste your code to investigage
avatar
i*r
12
那是什么物质在爆炸呢?
短路也不可能达到原子弹爆炸的高温呀。

【在 t******g 的大作中提到】
: 敲的是引爆装置的电子系统, 造成短路, 引起爆炸
avatar
f*Q
13
浮点运算还真有可能。

【在 s*****k 的大作中提到】
: 碰到一个非常困惑的问题
: 比如有一个浮点正数数组a[],
: 然后我通过一个for循环找到这个数组里面最小的数,
: 赋值为b,
: 然后for循环把a里每个数都减去这个b,
: 得到新的a.
: 那么这a[]里面一定有一个为0.0
: 我用 a[i]==0.0 来找这个index i,
: 发现有时候找不到,原来有时候减完b后
: 的a[]本来应该为0.0的那个数是一个非常小的数,而不等于0.0

avatar
c*c
14
扔下那个井凭啥会炸? 改装后就是让让它撞上东西就能爆炸,第一次可能井下沙太多
被缓冲了。台词里说过detonated by impact之类的东西。

【在 i******r 的大作中提到】
: 那是什么物质在爆炸呢?
: 短路也不可能达到原子弹爆炸的高温呀。

avatar
O*d
15
浮点数计算结果判断,不要用==。 一般用一个小范围来判断。两个相同值的浮点数相
加,和同一个值的浮点数乘以2,结果一般不会一样的。 就是a + a一般不等于 a * 2.
0, 但结果非常接近。 a - a不一定是0,但非常接近0。 我以前用过一个compiler,
写的程序运行结果预期是0的,变成一个几千次方的极大数。原因是指数部分从极负变
成极正。 类似例子是8bit的整数减法,-127 - 1 == 128.
avatar
t*g
16
电子装置导致触发子弹,子弹射入core引起爆炸, 这是原子弹的trigger 方式, H 蛋
也一样吧?
avatar
o*o
17
a - a 应该是等于 0 的。前面有位说的对,中间有其他过程。
avatar
i*r
18
那就是说,发生的不是聚变反应是裂变反应。因为除了爆炸原子弹的方式之外不可能出
现聚变反应发生的条件。
那这样的话,剧情中的氢弹就多此一举了,直接放个原子弹在那就行了。

【在 t******g 的大作中提到】
: 电子装置导致触发子弹,子弹射入core引起爆炸, 这是原子弹的trigger 方式, H 蛋
: 也一样吧?

avatar
M*0
19
刚做了实验,明明是0
avatar
s*k
20
代码其实挺复杂的,
我只是把问题抽象出来说了。
其实我自己另外写了一段简单的代码,
减完后的a[]里最小值是等于0.0的
我原来的代码其实结果总是合理的,
只是我觉得可能隐藏着错误

I

【在 a******d 的大作中提到】
: assuming fn is the min of f[0-m], then fn-fn=0, and others fi - fn >= 0. I
: don't see why the n'th subtraction isn't 0.
: paste your code to investigage

avatar
s*k
21
我用的是cygwin 里面的 gcc 3.4.4
现在发现只要把 -Ox 的优化参数去掉,
就可以用 a[i]==0.0
加上优化选项出来的a[i]最小的那个数是个量级是
10^-15 到 10^-18 的一个很小的数

2.

【在 O*******d 的大作中提到】
: 浮点数计算结果判断,不要用==。 一般用一个小范围来判断。两个相同值的浮点数相
: 加,和同一个值的浮点数乘以2,结果一般不会一样的。 就是a + a一般不等于 a * 2.
: 0, 但结果非常接近。 a - a不一定是0,但非常接近0。 我以前用过一个compiler,
: 写的程序运行结果预期是0的,变成一个几千次方的极大数。原因是指数部分从极负变
: 成极正。 类似例子是8bit的整数减法,-127 - 1 == 128.

avatar
s*k
22
还有一个奇怪的地方是如果在一些地方加些
printf,那么最小的a[i]就是0.0
和优化选项没关系了

2.

【在 O*******d 的大作中提到】
: 浮点数计算结果判断,不要用==。 一般用一个小范围来判断。两个相同值的浮点数相
: 加,和同一个值的浮点数乘以2,结果一般不会一样的。 就是a + a一般不等于 a * 2.
: 0, 但结果非常接近。 a - a不一定是0,但非常接近0。 我以前用过一个compiler,
: 写的程序运行结果预期是0的,变成一个几千次方的极大数。原因是指数部分从极负变
: 成极正。 类似例子是8bit的整数减法,-127 - 1 == 128.

avatar
O*d
23
你不知道优化做了什么东西。 我以前做过aeronics 的软件,飞机上用的软件不允许
compiler优化。 compiler甚至不能有优化的选项,也不能有优化的能力。 理由
就是优化会引进未知因素。 一切优化必须人工在source code水平上来做,并且
要通过无数的验证。 优化是一个非常费时费力的过程,所以每一个优化都要经过
一个悠长的技术,财务,人力资源上的讨论批准。

【在 s*****k 的大作中提到】
: 还有一个奇怪的地方是如果在一些地方加些
: printf,那么最小的a[i]就是0.0
: 和优化选项没关系了
:
: 2.

avatar
a*l
24
正如大家猜测的,原因是有其他的中间过程,你的"抽象"其实就把浮点的问题给抽象掉了.

【在 s*****k 的大作中提到】
: 代码其实挺复杂的,
: 我只是把问题抽象出来说了。
: 其实我自己另外写了一段简单的代码,
: 减完后的a[]里最小值是等于0.0的
: 我原来的代码其实结果总是合理的,
: 只是我觉得可能隐藏着错误
:
: I

avatar
s*k
25
刚才找到了一篇讲float-point arithmetic
的文章,在这里
http://hal.archives-ouvertes.fr/hal-00128124/en/
没工夫细看。但是下面这段话(在第二页)
里面讲的浮点计算的pitfall可能好多人都不知道
第二条说浮点计算不是deterministic的。
这让我想起以前好像看一个c faq里面说
计算sin(x)也不是deterministic,也就是说你在程序的两个地方
对同一个x算sin(x)的值是不一样的,当时没看懂。
我以前只当float计算就是要注意rounding error,
用abs(x-y)现在看来好像不是
Despite, or perhaps because of, the prevalence of “IEEE-compliant” systems,
there exist a number of myths of what IEEE-compliance really entails from
the
point of vie

【在 O*******d 的大作中提到】
: 你不知道优化做了什么东西。 我以前做过aeronics 的软件,飞机上用的软件不允许
: compiler优化。 compiler甚至不能有优化的选项,也不能有优化的能力。 理由
: 就是优化会引进未知因素。 一切优化必须人工在source code水平上来做,并且
: 要通过无数的验证。 优化是一个非常费时费力的过程,所以每一个优化都要经过
: 一个悠长的技术,财务,人力资源上的讨论批准。

avatar
s*k
26
第24页给了个例子,
说了加不加优化选项可能使
运算结果相差很大

【在 s*****k 的大作中提到】
: 刚才找到了一篇讲float-point arithmetic
: 的文章,在这里
: http://hal.archives-ouvertes.fr/hal-00128124/en/
: 没工夫细看。但是下面这段话(在第二页)
: 里面讲的浮点计算的pitfall可能好多人都不知道
: 第二条说浮点计算不是deterministic的。
: 这让我想起以前好像看一个c faq里面说
: 计算sin(x)也不是deterministic,也就是说你在程序的两个地方
: 对同一个x算sin(x)的值是不一样的,当时没看懂。
: 我以前只当float计算就是要注意rounding error,

avatar
s*k
27
哥们你说一下原因吧。
我以前对这个的理解就是rounding error。
事实上 abs(a)<10e-20也不一定对啊
我得到的x-x 常常是 1e-16这个量级的

10e-

【在 U********d 的大作中提到】
: 浮点判零是一个经典问题啊,一定不能a==0.0,应该用类似于if(a<10e-20 && a>-10e-
: 20)的条件判断。
: 至于原因嘛……嘿嘿,不说。

avatar
a*l
28
其实他的结论"同一个计算的结果可能是不同的"又对又不对.的确,x+y=z即使x,y是相同
的结果z也可能是不同的,但是原因是源代码和执行代码的区别,而不是说浮点计算的结
果在不同的时候会不同(针对硬件出来的结果而言).他说了很多时间,其实就是说,不要
光看源代码就说"计算值应该是多少"或者说"程序的路径应该是怎样的",因为有很多东
西可能会让这东西变化.

【在 s*****k 的大作中提到】
: 第24页给了个例子,
: 说了加不加优化选项可能使
: 运算结果相差很大

avatar
O*d
29
很有帮助。

【在 s*****k 的大作中提到】
: 刚才找到了一篇讲float-point arithmetic
: 的文章,在这里
: http://hal.archives-ouvertes.fr/hal-00128124/en/
: 没工夫细看。但是下面这段话(在第二页)
: 里面讲的浮点计算的pitfall可能好多人都不知道
: 第二条说浮点计算不是deterministic的。
: 这让我想起以前好像看一个c faq里面说
: 计算sin(x)也不是deterministic,也就是说你在程序的两个地方
: 对同一个x算sin(x)的值是不一样的,当时没看懂。
: 我以前只当float计算就是要注意rounding error,

avatar
s*k
30
google 的 group里面问了,
下面这个人的答案我觉得不错
That article is very relevant, and well-worth reading thoroughly if
you have time!
It's difficult to improve on what's in the article. But in short, the
number one cause of problems like the one you mention (assuming that
you're already happy with the basics of floating-point) is that
arithmetic calculations can legally be carried out in greater
precision that you expect, and that it can be hard to predict when
this is going to happen: a single expression might

【在 O*******d 的大作中提到】
: 很有帮助。
avatar
a*l
31
which google group? can you give a link?

【在 s*****k 的大作中提到】
: google 的 group里面问了,
: 下面这个人的答案我觉得不错
: That article is very relevant, and well-worth reading thoroughly if
: you have time!
: It's difficult to improve on what's in the article. But in short, the
: number one cause of problems like the one you mention (assuming that
: you're already happy with the basics of floating-point) is that
: arithmetic calculations can legally be carried out in greater
: precision that you expect, and that it can be hard to predict when
: this is going to happen: a single expression might

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。