2017-06-19 18 views
0

我有值的縮放功能,這看起來是這樣的:如何處理十進制運算錯誤?

r = a/b*c; 

其中R,A,B,C是小數。

大部分的時間,它工作正常,但有時我得到這樣的:

1.5M/3.09785668M*3.09785668M => 1.5000000000000000000000000001M 

這對我來說是一個問題,因爲在我的計算時間,錯誤升級。

什麼是檢測和消除這類錯誤的最佳方法?

+7

先乘以然後除 –

+0

任何確定的特定時間發生這種情況前:非常大的值等?此外,如果您嘗試'r = a /(b * c)'或'r =(a/b)* c'(根據您的計算要求),請檢查在這些情況下會發生什麼。 –

+0

@SivaGopal:應該是r = a /(b /)或r =(a * c)/ b - *&/具有相同的優先順序,因此從左到右進行評估。 – PaulF

回答

1

檢測

r = a/b*c; 
Debug.Assert(r*b/c == a, "Not good"); 

避免非終止子的結果,但仍然是脆弱的精度損失和非終止的最終結果

r = a*c/b; 

所以基本上,這兩種問題的子結果是(1)有限的精確損失和(2)非終止號碼

(1):

var loss1 = 1.000000000000000000001m * 1.000000000000000000001m; 
// should be 1.000000000000000000002000000000000000000001m 
// will be be 1.000000000000000000002m 

(2):

var loss2 = 1m/3m; 
// should be 0.333333333333333333333.. infinite line of 3 
// will be be 0.3333333333333333333333333333M 

第一種可以在乘法和除法發生,第二類僅在分裂。第一類可以通過增加精度來修正,第二類只能通過攜帶分數來修正,而不是試圖創建任何有限精度的單個實數。