今天在某. NET Core 群中看到有人在问 Math.Round 的问题. 其实这个问题之前有很多人遇到了, 在此总结一下.
开发者为了实现小数点后 2 位的四舍五入, 编写了如下代码,
- Copy
- 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 提供了非常多的重载方法, 其中有两个重载方法是,
- Copy
- 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 - 四舍六入五成双
所以如果我们希望的到一个理想中四舍五入的结果,, 我们可以改用如下代码:
- Copy
- var num = Math.Round(12.125, 2, MidpointRounding.AwayFromZero);
[小技巧] 你真的了解 C# 中的 Math.Round 么?
来源: http://www.bubuko.com/infodetail-3367520.html