Dot-Net
為什麼.NET 預設使用銀行家的四捨五入?
根據文件,該
decimal.Round方法使用對大多數應用程序不常見的取整算法。所以我總是最終編寫一個自定義函式來執行更自然的四捨五入算法:public static decimal RoundHalfUp(this decimal d, int decimals) { if (decimals < 0) { throw new ArgumentException("The decimals must be non-negative", "decimals"); } decimal multiplier = (decimal)Math.Pow(10, decimals); decimal number = d * multiplier; if (decimal.Truncate(number) < number) { number += 0.5m; } return decimal.Round(number) / multiplier; }有人知道這個框架設計決定背後的原因嗎?
框架中是否有任何內置的半舍入算法實現?或者也許是一些非託管的 Windows API?
decimal.Round(2.5m, 0)對於只寫期望 3 結果卻得到 2的初學者來說,這可能會產生誤導。
可能是因為它是一個更好的算法。在執行多次舍入的過程中,您將平均得出所有 0.5 的最終舍入均等。例如,如果您要添加一堆四捨五入的數字,這可以更好地估計實際結果。我會說,即使這不是某些人所期望的,但這可能是更正確的做法。
其他解釋為什麼銀行家的算法(又名四捨五入到偶數)是一個不錯的選擇的原因是非常正確的。在最合理的分佈上,它不會像零差一半方法那樣受到負偏或正偏的影響。
但問題是 .NET 為什麼預設使用 Banker 的實際舍入 - 答案是 Microsoft 遵循IEEE 754標準。這也在MSDN for Math.Round的備註下提到。
另請注意,.NET 通過提供
MidpointRounding枚舉來支持 IEEE 指定的替代方法。他們當然可以提供更多解決關係的替代方案,但他們選擇只滿足 IEEE 標準。