1

可能重複:
Matlab gives wrong answerMatlab的 - 「0:1.1:1」 意外精密行爲

任何人都可以向我解釋爲什麼會發生以下情況時,我用的是0:.1:1 - 範圍功能?

>> vecA = 0:.1:1; 
>> vecB = [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]; 
>> vecA == vecB 

ans = 

    1  1  1  0  1  1  1  1  1  1  1 

爲什麼vecA(4)不等於0.3?他們完全一樣;)

vecA = 

    Columns 1 through 7 

     0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 

    Columns 8 through 11 

    0.7000 0.8000 0.9000 1.0000 

>> vecB 

vecB = 

    Columns 1 through 7 

     0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 

    Columns 8 through 11 

    0.7000 0.8000 0.9000 1.0000 

我覺得這裏採用的是精度的問題?或者我的理解有問題?

+0

我使用7.11.1.866(R2010b)Service Pack 1 – powerbar

+0

有趣的事情:'vecA(4) - 0.3 = 1.0e-016 * 0.5551' – powerbar

+0

下面是一個比較實際值的簡單方法:'sprintf('%。20f \ n',vecA(4),0.3)'。也看看(0.3) – Peter

回答

3

計算機是二進制的,它們的本地浮點格式不能精確地存儲小數部分。 (您可以使用比率類型或定點小數類型,但使用這些類型的計算速度要慢得多。)

因此,爲相等性測試浮點值實際上毫無用處。請檢查差異的絕對值。

你一定要讀What Every Computer Scientist Should Know About Floating Point Arithmetic

(也有一些簡單的解釋,如http://floating-point-gui.de/但你應該用這些來幫助您瞭解戈德堡的論文,而不是取代它)


什麼你實際上在這種情況下看到的是0.2 + 0.1 != 0.3(該範圍使用第一個版本,vecA(3) = vecA(2) + step

+0

我知道浮點基礎知識,但會給這篇論文一個嘗試。謝謝。無論如何,我會期望matlab的簡單範圍函數在這裏更加健壯...... – powerbar

+1

'計算機是二進制的,它們不能精確地存儲小數。「是一個不真實的陳述。 – rubenvb

+0

@rubenvb:澄清引用原生格式。當然,您可以將有理數(包括小數)表示爲用戶定義類型,但數學計算效率很低。 –

2

這很可能是有限精度浮點運算的一般結果。嘗試使用

format long 

然後輸出值以查看更精確的顯示。我會想象內部vecA創建使用循環和值增加或範圍的分裂,這是造成微小的差異。正如你正在等同於浮點值,你會遇到這個問題。一般來說,這是浮標直接比較的常見結果。

+0

如果使用循環,我希望總結出錯?或者以某種方式對稱? – powerbar

+0

我明白你的意思,但是當你的值和由你無權訪問的另一個人代碼計算出的值進行比較時,很難假定任何浮點運算。 – mathematician1975

+0

我在我的代碼中使用'abs(vecA - vecB) powerbar