2014-03-12 81 views
0

我試圖用Matlab解決一些問題,並在dt * j爲整數時存儲結果,使用下面的代碼 。matlab mod()函數給出了錯誤的答案

j=1; 
dt = 1E-05; 
a=[]; 
while dt*j <=20 
    if mod(dt*j,1) ==0 
     a=[a;[dt*j,j]]; 
    end 
j=j+1; 
end 

但是Matlab給了我不正確的結果。如下所示缺少一些整數(3,6,7,11等)。

a = 
1  100000 
2  200000 
4  400000 
5  500000 
8  800000 
9  900000 
10  1000000 
16  1600000 
17  1700000 
18  1800000 
19  1900000 
20  2000000 

我試過再次使用dt = 1E-4,它給出了正確的結果。誰能告訴我這裏發生了什麼?謝謝。

+3

浮點精度錯誤的另一個例子。它不是'mod'那是錯誤的,'dt * j'不是精確的預期值。 – Daniel

+0

是的,dt * 300000 == 3 ans = 0但dt * 400000 == 4,ans = 1我很困惑,因爲只有一些數字丟失,但我想它涉及如何計算機存儲號 – user3413078

+0

這是一個浮點算術。有一些問題:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Daniel

回答

2

不要直接比較浮點數與==,但檢查而不是他們是非常接近:

j=1; 
dt = 1E-05; 
a=[]; 
while dt*j <=20 
    if abs(mod(dt*j,1)) < 1e-10 
     a=round([a;[dt*j,j]]); 
    end 
j=j+1; 
end 
+0

謝謝!有用。我之前使用過這個==比較,但這個問題直到今天才出現...... – user3413078

0

我猜有一些奇怪的舍入誤差。我試過你的代碼,我得到了相同的結果。一種方法是使用mod(dt * j,1)== 0,使用mod(dt * j,1)< dt或mod(dt * j,1)< thresh,您可以在其中設置閾值足夠接近零,它會做的伎倆。

從雙精度浮動數字格式頁面上的維基百科頁面,它表示: 1.0000000000000002,最小的數字> 1。由此我推斷,使用雙倍,你得到約2E-16數值分辨率。因此,您可以使用2E-15的閾值並且更安全。

+0

數值分辨率由'eps'給出,實際上它大約是2e-16 –

相關問題