2016-01-23 35 views
0

該值是絕對整數,不是一個值得懷疑的浮點數,並且它不是溢出,因爲double值可以保持到2^1024。使用MATLAB的二項式的精度錯誤?

fprintf('%f',realmax) 
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

我面臨nchoosek功能,它不準確產生的問題重視

fprintf('%f\n',nchoosek(55,24)); 
2488589544741302.000000 

雖然它是2關於該binomian(n,m)=binomial(n-1,m)+binomial(n-1,m-1)如下百分比誤差

fprintf('%f',nchoosek(55-1,24)+nchoosek(55-1,24-1)) 
2488589544741301.000000 

ps:確切的數值是2488589544741300

this demo shows

MATLAB有什麼問題?

回答

2

您對realmax函數的理解是錯誤的。這是可以存儲的最大值,但是如此大的數字會導致浮點精度誤差遠高於1.不能存儲在雙精度值中的第一個整數爲2^53+1,請嘗試2^53==2^53+1作爲一個簡單示例。

如果符號工具箱是可用的,實現的解決方案最簡單的就是使用它:

>> nchoosek(sym(55),sym(24)) 

ans = 

2488589544741300 
1

看起來像一個整數(55)的東西與實際上是一個整數(根據變量類型)之間有區別。

您計算的方式,您的值存儲爲浮點數(這是realmax指向您的最大正浮點數 - 檢查intmax('int64')爲最大可能的整數值),因此您可以獲得浮點錯誤。大數值的絕對差值2並不意外 - 實際百分比誤差很小。

另外,您在格式字符串中使用了%f - 例如,要求它顯示爲浮點。

對於nchoosek,具體來說,從文檔中,輸出作爲與輸入n和k相同類型的非負標量值返回,或者如果它們是不同類型的非雙類型(僅限於如果一個是雙精度型,則有不同的輸入類型)。

在Matlab中,當您直接在函數輸入中輸入數字時,它通常默認爲浮點數。你必須強制它是一個整數。

嘗試代替:

fprintf('%d\n',nchoosek(int64(55),int64(24))); 

注:%d%f,轉換兩個輸入具體整數。 nchoosek的輸出應該是int64

+1

非常感謝你的努力,但[希望你在張貼之前檢查你的代碼(HTTP:// ideone的.com/rP8kEG) – Abra001

1

我無法訪問MATLAB,但由於您明顯可以使用Octave,因此我會發布基於此的觀察結果。

如果你看一下使用edit nchoosek或倍頻源代碼here,你會看到,計算二項式係數的公式很簡單:

A = round (prod ((v-k+1:v)./(1:k))); 

正如你所看到的,有k區,每個區有可能引入一些小錯誤。下一行嘗試是有益的,警告你的精度損失的可能性:

if (A*2*k*eps >= 0.5) 
    warning ("nchoosek", "nchoosek: possible loss of precision"); 

所以,如果我可以稍微修改你的最後一個問題,什麼是錯的八度?我會說沒有錯。作者顯然知道不準確的可能性,並且包含一個檢查,以在有可能出現時警告用戶。所以這個功能按照預期工作。如果您的應用程序需要比內置函數提供的更高的精度,則看起來您需要編寫(或查找)以更高精度計算中間結果的內容。