[小技巧]你真的瞭解C#中的Math.Round麼?
阿新 • • 發佈:2020-09-09
開發者為了實現小數點後 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);