2012-01-22 129 views
6

我想比較一個雙精度數組爲平等,但在某些情況下永遠不會識別平等。我懷疑這與雙倍體現的方式有關(例如1.0比1.00),但我無法弄清楚。matlab雙比較

例如,我已經產生的數千雙值組成的陣列,最後幾個其中的某時刻在時間上由

10.6000 
-11.0000 
10.2000 
22.6000 
3.4000 

給出。如果我測試相等10.2(或10.2000)通過命令array==10.2(或array=10.2000),我返回一個0的數組。如果我手動將所顯示的值放入數組中(例如,array=[10.6000 -11.0000 10.2000 22.6000 3.4000]),則該命令成功(即,array==10.2返回0 0 1 0 0)。有人可以解釋爲什麼如果我手動輸入值相等成功,但如果數組是在程序的上下文中生成失敗?我可以通過使用近似值而不是精確比較來糾正比較失敗(例如,(array<10.20001) & (array>10.19999)),但這似乎並不令人滿意。

編輯:數組中的值是通過迭代加或減一個常數double(例如,0.2)生成的。因此該陣列的模數0.2因此應該在任何地方都等於0。事實上,每個元件的彈性模量等於或者00.2,如下所示爲數字的陣列中的上述序列:

mod(array,0.2) 
... 
0.2000 
    0 
0.2000 
0.2000 
    0 

再次,如果值被放置在手動一個陣列和所述模數取得所有0 s的期望值。

回答

6

原因是MATLAB截斷了數組中的數字,以便在顯示小數點後只保留4位數字。也就是說,數組的實際值可能是[10.600000000001, -10.99999999999, ...]。你是對的,這是由於計算機中浮點數的內部表示,這可能會導致計算中的微小錯誤。我個人認爲有兩種解決方案,一種是近似匹配,就像你做的那樣,另一種是首先將數組四捨五入(比如FileExchange中的this tool),然後做精確匹配。

+0

非常有幫助。一個後續問題是我的數字是通過在一個循環中的許多循環上增加或減少一個常量(例如,'0.2')而產生的,所以在數學上,當以0.2爲模時,數組中的數字應該等於0('mod(array ,0.2)')。事實上,他們不是。它們等於0或0.2。當然,當我通過手動輸入數組的方式對數組中的任何數進行模0.2運算時,給出的期望值爲0。你能解釋這種行爲嗎?謝謝! – user001

+1

這涉及如何在計算機中表示浮點數。衆所周知的事實是計算機使用二進制而不是十進制。然而,二進制問題即有限分數,例如十進制0.2,不能用二進制有限數字表示。也就是說,計算機中0.2的二進制表示實際上是0.001110011100111 ...,這是無止境的。但是,MATLAB使用64位來表示「Single」,這可能會導致2 ^( - 65)的錯誤。這個錯誤是相當小的,但是當有很多迭代時,它可能會累積。 – grapeot

+0

精彩的解釋。非常感謝。 – user001

2

東西可能在某個地方是單精度的,而在其他地方可能是雙精度的。例如,二進制表示每個中的10.2是不同的,因爲它們在不同位數之後終止。因此,它們是不同的:

>> if (single(10.2) == 10.2) disp('honk'); end 
>> if (single(10.2) == single(10.2)) disp('honk'); end 
honk 

你需要中的一些小的差異檢查等式:

eps = 0.001; 
result = abs(array-10.2) < eps; 

可以使用衛生組織找到一個陣列中使用的精確度:

>> whos A 
    Name  Size   Bytes Class  Attributes 

    A   1x2     8 single  
+0

謝謝@Alex。你可以在葡萄酒的帖子下看到我的評論嗎?如果我的數組是由一系列在循環上下文中加上或減去0.2(double)產生的數組,那麼數組中每個元素的模可以是0或0.2,這是沒有意義的。我使用'whos'命令檢查了我的數組的精度(謝謝),它是雙精度的,就像我的標量比較器變量一樣。 – user001

+1

0.2不能完全表示爲二進制浮點數(參見http://www.h-schmidt.net/FloatApplet/IEEE754.html),它是0.1001 [1001 ...]的連續分數。因此,將0.2加入某件事可能不會完全符合您的想法。如果正確性很重要,那麼在你的問題的最小單位中工作,在這種情況下,最簡單的工作方式是10x,然後在數字上加2,然後檢查mod(num,2),然後在最後分開10。 – Alex

+0

非常感謝。該問題通過添加/減去0.25來解決,這很有意義,因爲根據您提供的小程序,0.25可以完全表示爲二進制浮點數。我想最好的地方找到更多的信息將是一篇關於數字的浮點表示的文章。 – user001

1

創建一個將接受模值(從3到9;即從Z3到Z9)的MATLAB函數文件,並且 將輸出由模數條件描述的最小可能值。

樣本模擬:

Z = [3 4 5]; %Modulo Z3,Z4和Z5

r = [2 1 4]; %剩餘值

最可能的值是29。

的Z輸入必須是一個數組矩陣...其中在可至9 3鍵入任何號碼....並可以以任何順序鍵入3,4,5,6,7,8,9,在任何配對或分組...

的r個輸入應等於的Z輸入太數...

輸出應該通過模數條件產生儘可能少的值...