1. 程式人生 > 實用技巧 >[小技巧]你真的瞭解C#中的Math.Round麼?

[小技巧]你真的瞭解C#中的Math.Round麼?

開發者為了實現小數點後 2 位的四捨五入,編寫了如下程式碼,

var num = Math.Round(12.125, 2);

程式碼非常的簡單,開發者實際得到的結果是 12.12, 這與其所預期的四捨五入結果 12.13 相悖。

其實產生這個結果的原因是由於Math.Round預設使用的並非是四捨五入的原則,而是四捨六入五成雙的原則。

四捨六入五成雙

所謂的四捨六入五成雙,就是說當確定有效位數之後,有效位數的下一位如果小於等於 4 就捨去,如果大於等於 6 就進一,當有效位數的下一位是 5 的時候

  • 如果 5 前面為奇數,就舍五進一
  • 如果 5 前面為偶數,就舍五不進(0 是偶數)

從統計學上講,四捨六入五成雙比四捨五入要更精確,因為大量計算的情況下,四捨五入逢五進一,會導致結果偏向大數。

例如:

1.15+1.25+1.35+1.45 = 5.2

如果有效位數是小數點後一位,使用四捨五入原則得到的結果

1.2 + 1.3 + 1.4 + 1.5 = 5.4

而使用四捨六入五成雙原則得到的結果是

1.2 + 1.2 + 1.4 + 1.4 = 5.2

由此可見四捨六入五成雙原則得到的結果更為精確。

Math.Round 的四捨五入

那麼如何使用Math.Round實現預期的四捨五入呢?

其實 C#中的Math.Round提供了非常多的過載方法,其中有兩個過載方法是,

public static double Round (double value,
int digits,
MidpointRounding mode);
public static decimal Round (decimal d,
int decimals,
MidpointRounding mode);

這兩個方法都提供了第三個引數mode,mode是一個MidpointRounding的列舉變數,它有 2 個可選值

  • AwayFromZero - 四捨五入
  • ToEven - 四捨六入五成雙

所以如果我們希望得到一個理想中四捨五入的結果,我們可以改用如下程式碼:

var num = Math.Round(12.125, 2,
MidpointRounding.AwayFromZero);