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

今天在某.NET Core 羣中看到有人在問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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章