2012-02-13 23 views
1

我的應用程序需要執行一些操作:>,<,==,!=,+, - ,++等(但沒有除法)。這些數字有時是整數,而更少有浮點數。什麼時候雙打開始失去精確度?

如果我在內部使用「double」類型(由IEEE 754定義),即使對於整數,直到我可以安全地使用它們,就好像它們是int s一樣,沒有運行奇怪的舍入錯誤例如,n == 5 & & n == 6都是真的,因爲他們四捨五入到相同的數字)?

很顯然,各種操作(+, - 等)的第二個輸入始終是一個整數,我知道在0.000 [...] 01之後我會從開始就遇到麻煩。

作爲獎勵答案,同樣的問題,但爲float

+3

請選擇「c#」或「C++」,因爲「double」在這些語言之間執行的並不相同。 – Yuck 2012-02-13 16:32:28

+0

在我脫落之前,我可以走多遠到懸崖邊緣?當你可以簡單地把它們看作整數時,你爲什麼會冒任何整數的精度損失?什麼是想要使用雙重的理由? – 2012-02-13 16:33:12

+4

我不認爲有可能構建一個例子,在任何情況下'n == 5 && n == 6'都會評估爲「true」。 – dasblinkenlight 2012-02-13 16:33:17

回答

0

C#參考: 但是,請注意小數類型的範圍小於一倍。這是雙倍可以保持更大的價值,但它通過失去精確度。或者,如MSDN上所述:

十進制關鍵字表示128位 數據類型。與浮點型 類型相比,小數類型具有更高的精度和更小的範圍,其中 使其適用於財務計算和 貨幣計算。下表中顯示了 類型的近似 範圍和精度。

decimaldouble之間的主要區別是,decimal is fixed-point and double is floating point。這意味着小數存儲精確值,而double表示由小數表示的值,並且不太精確。 A decimal是128位,所以需要雙倍空間來存儲。 decimal的計算也較慢(測量!)。

如果您需要更大的精度,則可以使用.NET 4中的BigInteger。(您需要自己處理小數點)。在這裏你應該知道,BigInteger是不可變的,所以對它的任何算術運算都會創建一個新的實例 - 如果數字很大,這可能是性能的縮影。

我建議你看看你需要多少精度。也許你的算法可以使用規範化的值,可以更小?如果性能問題,內置浮點類型中的一種可能會更快。

8

比特在IEEE-754雙尾數的數目是52,並且有一個額外的隱含位,始終是1。這意味着可以包含恰好是2^53,或9007199254740992

甲最大值浮點尾數是23位,也是一個隱含位。可精確表示的最大整數是2^24或16777216.

如果您的意圖只是保存整數值,通常會有一個64位整數類型,比雙精度值更合適。

編輯:最初我有2^53-1和2^24-1,但我意識到沒有必要減去1 - 偶數可以利用尾數右邊的隱含0位。

+1

'9007199254740992.0 == 9007199254740993.0'的計算結果爲true,並且看起來是第一對計算相同數字的整數(在數學意義上)。 – Guvante 2012-02-13 22:20:38

+1

說2^53是「可以包含的最大值」並不完全正確。你真正想要說的是2^53是最大的整數n,使得範圍[-n,n]中的每個整數都可以精確地表示爲雙精度。 – 2012-02-14 15:46:37

+0

@StephenCanon,謝謝澄清。有時候我的語言有點不準確。當然,如果尾數在尾數的右邊有零,也可以精確地表示更大的數字,儘管當您嘗試使用它時可能會有一些細微的變化。 – 2012-02-14 16:23:13