小心Math.Round()

double d = Math.Round(20.5);

d = Math.Round(21.5);

在C#中,執行上面的兩行程式會出現什麼結果呢?

Math.Round()一般給人的感覺就是要進行四捨五入。所以就會想說,那應該是 21.0跟 22.0吧。

可是在C#中執行的結果,卻出乎意料,結果是20.0跟22.0。

怎麼會這樣!!

看起來有點不按牌理出牌。我查了一下MSDN,Math.Round()的運作原理如下:

傳回值

最接近 a 的整數。如果 a 的小數部分落在兩個整數中間,一個是偶數,另一個是奇數,則會傳回偶數

說明

這個方法的行為遵循 IEEE Standard 754 第 4 節。這種捨入有時稱為捨入至最接近值或銀行家捨入。這樣會將一致四捨五入單向中點值得出的四捨五入錯誤降至最低。 

它的原理是希望能將誤差降到最低,不過,卻跟一般人的想法不一樣。

另外還發現原來Math.Round()的引數不只一個,它還可以有第二個引數。

第二個引數是一個列舉值,叫作MidPointRounding

它有兩個列舉值:AwayFromZero以及ToEven。預設下就是使用ToEven。不過,一般人比較能接受的應該是AwayFromZero吧。

所以下次要使用Math.Round()時,請確定你要的運作模式,以免算出來的結果不是你預期的。

留言

這個網誌中的熱門文章

DOS Batch指令檔中如何記錄log資訊

用捷徑方式執行需帶入命令列參數的Windows Form程式

使用regular expression來match中括號(square bracket)