15402 发表于 2010-10-26 14:58:47

matlab的0.35问题

最近在做程序时,发现一个问题,关于数值精度的,暂且称之为“0.35问题”
代码如下:
H=0.35;
X=35*0.01;
X,H
if(X>=0.0 && X<=H)
'a'
elseif (X<=1.0 && X>H)
'b '
end
这段程序,执行结果应该是‘a’,即在屏幕上输出X和H的值,再输出字符a,但执行的结果却是‘b’。而除了0.35以外,0.45、0.55、0.25都没这个问题,0.345同样有这个问题。就这个小问题,导致我的整套程序里面出了意向不到的结果,花了很长时间才发现是这个原因。目前我我是通过算法上的调整来解决的。
谁能从数值精度上解释一下原因?或者从计算机的2进制转换上解释一下原因?
我用的是MATLAB2006,另外Fortran6.6版本也有这个问题,而c语言的tc2.0编译器没有这个问题,其他的编译器没试过。

bainhome 发表于 2010-10-26 16:40:24

最近在版面里遇到的最有意思的问题,试了一下,结果如下:format long g
H=;
X=*.01;
X-H结果:ans =
Columns 1 through 3
   5.55111512312578e-017   5.55111512312578e-017   5.55111512312578e-017
Columns 4 through 6
                         0                         0                         0
Column 7
                         0

15402 发表于 2010-10-26 17:14:04

求解释:)...............

chenzhian 发表于 2010-10-26 17:14:09

那弱弱的问楼上的老师,象这种情况,是怎么产生的?应该怎么消除?
不至于出现楼主的程序出现错误的结果。

15402 发表于 2010-10-26 17:31:43

4# chenzhian
我是通过算法调整来实现的,即判断两数相减与0的关系,再做下一步运算

qibbxxt 发表于 2010-10-26 17:51:47

这应该是计算机二进制的问题,判断是需要注意>> p=X-H

p =

    5.551115123125783e-017
类似还有

>> 0.3-0.2-0.1
ans =
   -2.775557561562891e-017

bainhome 发表于 2010-10-26 23:13:25

是这意思,可以参阅微机原理中关于二进制和数值分析关于计算机截断误差方面的内容,即可了解此问题的要害。
事实上我们学过数值分析后,在计算过程中都应该避免这种简单相减直接判为零的情况,而是应该令其小于一个计算机的阈值,这个值在MATLAB中是给出了规定的,例如可以用:X-H<eps或者乘以一个较大的数字再行比较等。

taohe 发表于 2010-10-27 13:18:57

这个和电脑对浮点数的表示和使用有关,我们知道,由于有效位数的限制,电脑无法准确表示每个浮点数,由此也就有了单精度和双精度浮点数的区别。也就产生了数值计算的一些特点,其中一条就是说数值计算不封闭,举例来说,在数值计算中算式1/3*3不等于1。等结果非常接近1。正式因为这样的原因,人们在程序中需要判断两个浮点数是否相等的时候,不直接使用“==”,而是看它们是否足够接近。

lin2009 发表于 2010-10-27 20:43:23

也就是计算机用有限的数位表示浮点数(如1/3)而产生的舍入误差-有限位后的数字就被四舍五入了,如32位机的第33位及以后的数字(1或0,二进制表示)。
这个问题很容易被忽略。
不过,1/3*3 不等于1 的问题,Matalb新版本已经作了修正了,可以等于1了。可能是算法上作了调整。
我举其它的例子来说明舍入误差(截断误差)
1、>> a = 1e-15

a =

    1.000000000000000e-015

>> ((1+a)-1)/a

ans =

   1.110223024625157
看,简单的算式,就有11% 的相对误差。
页: [1]
查看完整版本: matlab的0.35问题