zoukankan      html  css  js  c++  java
  • [小技巧]你真的了解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);

    这两个方法都提供了第三个参数modemode是一个MidpointRounding的枚举变量,它有 2 个可选值

    • AwayFromZero - 四舍五入
    • ToEven - 四舍六入五成双

    所以如果我们希望得到一个理想中四舍五入的结果,我们可以改用如下代码:

    var num = Math.Round(12.125, 2,
    MidpointRounding.AwayFromZero);
  • 相关阅读:
    codeforces #601 div2 ABC~E1
    codeforces #600 div2 ABCD
    图形学 三次Hermite曲线绘制实现代码 javascript:es6+h5:canvas
    最小生成树(Prim / Kruskal)
    拓扑排序【Kahn算法(bfs)和dfs求拓扑序列及判环】
    Cow Traffic(正反向建图+DAG拓扑排序)
    JAVA大数
    【C/C++】关于strstr函数和c_str()函数
    【C/C++】关于函数调用传递实参
    2019上海icpc网络赛B. Light bulbs(思维+差分)
  • 原文地址:https://www.cnblogs.com/cxxtreasure/p/13642219.html
Copyright © 2011-2022 走看看