我的團隊正在使用將貨幣值暴露爲C#浮點加倍的財務軟件。偶爾,我們需要比較這些值,看看它們是否等於零,或者是否落在特定的限制之下。當我注意到這個邏輯出現意外的行爲時,我很快就瞭解了浮點雙精度所固有的舍入誤差(例如1.1 + 2.2 = 3.3000000000000003)。到目前爲止,我主要使用C#小數來表示貨幣值。爲浮點比較選擇一個Epsilon值
我的團隊決定使用epsilon值方法解決此問題。基本上,當你比較兩個數字時,如果這兩個數字之間的差值小於ε,那麼它們被認爲是相等的。我們實施以類似的方式這種方式爲下面的文章中描述: https://www.codeproject.com/Articles/383871/Demystify-Csharp-floating-point-equality-and-relat
我們面臨的挑戰已經確定小量適當的值。我們的貨幣值在小數點右側最多可以有3位數字(比例= 3)。這意味着我們可以使用的最大epsilon是.0001(任何更大的數字和第三位被忽略)。由於epsilon的值應該很小,我們決定將它移出一個小數點到.00001(爲了安全起見,你可以說)。 C#雙精度爲at least 15 digits,所以我相信如果小數點左邊的數字小於或等於10位數(15 - 5 = 10,其中5是小數位數爲在小數點右側)。用10位數字,我們可以將數值表示爲數十億,最高可達9,999,999,999.999。我們可能有數以億計的數字,但我們並不期望達到數十億,所以這個限制應該足夠了。
我選擇epsilon的這個值的理由是正確的嗎?我發現了很多討論這種方法的資源,但我找不到提供選擇epsilon指導的許多資源。
我認爲使用正常的,甚至DP,IEEE754不是一個偉大的財務計算思路。感知的智慧是使用C#的[decimal](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/decimal)類型;你考慮過這個嗎? –
@IsaacWoods我正在爲現成的財務軟件編寫插件代碼,所以我無法控制它正在使用的數據類型。我曾考慮將double值轉換爲小數,但如果double已經包含舍入錯誤,它只會被複制到小數點。 –
由於經歷了一些痛苦的經歷,從一位經理告訴我說:「你永遠不會讀200多張打卡。「,」我們預計不會進入數十億「這一形式的條款讓我非常緊張,你將如何執行這一限制?如果存在一段時間的通貨膨脹,會發生什麼情況?你以一家大型銀行作爲客戶?您的代碼與其他貨幣一起使用? –