2010-09-08 62 views
6

在我的機器上,當前的.net版本Math.exp(-1000)返回0.0,這是合理的,因爲 它是一個數字太小而無法表示爲double。大負數的Math.Exp

我可以依靠這個來保持其他機器以及未來的.net builts嗎? Msdn告訴我 Math.exp(Double.NegativeInfinity)返回0.0(因此我希望將來會保持這樣),但是-1000呢?

回答

4

Math.Exp()函數被定義爲對雙精度類型進行操作。請注意,exp(-1000)== 5.08e-435,遠低於可用double表示的最小絕對值。

我認爲可以肯定地說任何使用IEEE浮點數的環境,exp(-1000)都是0.0。 .Net永遠不會離開IEEE浮點。從更一般的角度來看,我猜你對小批量可靠地回合爲零感興趣。總之,是的,在IEEE。

但是,最好不要將此行爲設計到您的代碼中。正如Darin所建議的那樣,比較容差內的浮點值。如果您有處理非常小或大數量的原因,請考慮將數量作爲對數跟蹤並在對數域中執行操作(如果您需要乘數,添加對數等)。您可以使用高精度的數學庫,但即使數字變得非常小,計算也可能會出現較大的舍入誤差和較差的數值穩定性。

最後,如果您的意圖是計算1.0 - Math.Exp(-num)Math.Exp(-num) - 1,請查找庫函數,直接計算這些函數以獲得最佳精度。

2

不,你永遠不能相信double類型的變量完全等於某個東西。永遠不要寫這樣的東西。切勿使用==運算符來比較兩個雙操作數:

double d = ... 
if (d == 0.0) { 

} 

相反,你應該確定所需的精度始終與這個精密的工作:

double epsilon = 1e-5; 
double d = ... 
if (Math.Abs(d - 0.0) < epsilon) { 

} 
+0

downvote的任何原因? downvoting時請留言。 – 2010-09-08 13:53:34

1

使用內置的構建,他們都表示。

由於雙倍大小的限制,它應該保持不變,但我更喜歡使用內置於課程中的常量並由MSDN確認。

+0

您的內建結構究竟是什麼意思? – willem 2010-09-08 12:16:25

+0

@Willem - 我指的是使用'Double.NegativeInfinity',而不是限制操作中的幻數。 – 2010-09-08 12:20:05

1

不,它不是一個好主意,提醒這樣的例外。這不是一個拋出的異常,但是它太小而不能顯示,因此只給你0.0,這是一個例外。對於像這樣的東西,最好保持常量。

+0

引用來源?我認爲沒有理由相信有例外。 – recursive 2010-09-08 13:44:28

+0

不是傳統意義上的異常,而是更多的事實是變量類型無法處理數字,因此它給出的默認值爲0.0。所有異常無非就是您的代碼無法處理的東西。 – Adkins 2010-09-08 13:50:34