在我的機器上,當前的.net版本Math.exp(-1000)返回0.0,這是合理的,因爲 它是一個數字太小而無法表示爲double。大負數的Math.Exp
我可以依靠這個來保持其他機器以及未來的.net builts嗎? Msdn告訴我 Math.exp(Double.NegativeInfinity)返回0.0(因此我希望將來會保持這樣),但是-1000呢?
在我的機器上,當前的.net版本Math.exp(-1000)返回0.0,這是合理的,因爲 它是一個數字太小而無法表示爲double。大負數的Math.Exp
我可以依靠這個來保持其他機器以及未來的.net builts嗎? Msdn告訴我 Math.exp(Double.NegativeInfinity)返回0.0(因此我希望將來會保持這樣),但是-1000呢?
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
,請查找庫函數,直接計算這些函數以獲得最佳精度。
不,你永遠不能相信double類型的變量完全等於某個東西。永遠不要寫這樣的東西。切勿使用==
運算符來比較兩個雙操作數:
double d = ...
if (d == 0.0) {
}
相反,你應該確定所需的精度始終與這個精密的工作:
double epsilon = 1e-5;
double d = ...
if (Math.Abs(d - 0.0) < epsilon) {
}
使用內置的構建,他們都表示。
由於雙倍大小的限制,它應該保持不變,但我更喜歡使用內置於課程中的常量並由MSDN確認。
您的內建結構究竟是什麼意思? – willem 2010-09-08 12:16:25
@Willem - 我指的是使用'Double.NegativeInfinity',而不是限制操作中的幻數。 – 2010-09-08 12:20:05
downvote的任何原因? downvoting時請留言。 – 2010-09-08 13:53:34