代码之家  ›  专栏  ›  技术社区  ›  Bret Walker

在C中四舍五入到偶数#

  •  9
  • Bret Walker  · 技术社区  · 16 年前

    我没有看到我期望的数学成绩。

    return Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97
    

    正如我所理解的中点舍入。即使,第千位的5应该使输出为99.96。不是这样吗?

    我甚至尝试过这个,但它也返回了99.97:

    return Math.Round(99.96535789 * 100, MidpointRounding.ToEven)/100;
    

    谢谢

    7 回复  |  直到 16 年前
        1
  •  27
  •   Dan Tao    16 年前

    你实际上并不在中点。 MidpointRounding.ToEven 表示如果您有该号码 99.965 然后

    如果要将数字四舍五入到99.96,请执行以下操作:

    // this will round 99.965 down to 99.96
    return Math.Round(Math.Truncate(99.96535789*1000)/1000, 2, MidpointRounding.ToEven);
    

    嘿,这里有一个方便的小函数,可以在一般情况下执行上述操作:

    // This is meant to be cute;
    // I take no responsibility for floating-point errors.
    double TruncateThenRound(double value, int digits, MidpointRounding mode) {
        double multiplier = Math.Pow(10.0, digits + 1);
        double truncated = Math.Truncate(value * multiplier) / multiplier;
        return Math.Round(truncated, digits, mode);
    }
    
        2
  •  10
  •   Vinay Sajip    16 年前

    仅当您位于中点时,它才舍入到99.96,即99.965:

    C:\temp>ipy
    IronPython 2.6 Beta 2 (2.6.0.20) on .NET 2.0.50727.4927
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import clr
    >>> from System import Math, MidpointRounding
    >>> Math.Round(99.9651, 2, MidpointRounding.ToEven)
    99.97
    >>> Math.Round(99.965, 2, MidpointRounding.ToEven)
    99.96
    >>> Math.Round(99.9649, 2, MidpointRounding.ToEven)
    99.96
    >>> Math.Round(99.975, 2, MidpointRounding.ToEven)
    99.98
    >>>
    
        3
  •  5
  •   Noldorin    16 年前

    这个 MidpointRounding 只有当您试图舍入某个值时,该值才会起作用 正好是5。换句话说,该值必须为 99.965 MSDN page 更多信息。

        4
  •  4
  •   Lee    16 年前

    以下是一些对该主题有帮助的结果:

    Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97
    Math.Round(99.965, 2, MidpointRounding.ToEven);      // returning 99.96
    Math.Round(99.96500000, 2, MidpointRounding.ToEven); // returning 99.96
    

    中点正好是5。。。不是535789,不是499999。

        5
  •  0
  •   Reed Copsey    16 年前

    仅当值介于两个案例之间时,才会查看中点舍入。

    在你的例子中,它不是“5”,它是“535…”,所以它大于中点,并且大于0.96。要获得预期的行为,您需要trunctate到第三个小数点,然后使用middpointrounding.ToEven进行四舍五入。

        6
  •  0
  •   Ralf de Kleine    16 年前

    Math.Round“将十进制值四舍五入到指定数量的小数位数。”将99.96500000四舍五入时,将2舍五入到99.96,将99.96500001四舍五入到99.67。它对整个值进行四舍五入。

        7
  •  0
  •   BeemerGuy    15 年前

    如果是我,我不会使用 Math.Round() ,因为这不是你想要完成的。

    double num = 99.96535789;
    double percentage = Math.Floor(100 * num) / 100;  
    


    我把这个数字乘以 100 9996.535789 .
    然后将其放低,这与取整截然不同,返回最接近数字的最小整数,得到 9996 .
    然后除以 获得所需的 99.96 .

    附笔。
    地板 是的对立面 ,返回最接近该数字的最大整数。
    那么,这个上限, 9996.535789 9997 .
    两者都不同于 四舍五入 没有小数点,实际上返回与数字最接近的整数,无论它是小的还是大的——以最接近的为准;这就是为什么你会 99.97 四舍五入 .

        8
  •  0
  •   Abdel    5 年前

    感谢Dan Tao分享您的解决方案,但它总是给出错误的结果,例如4.485,因此我分享了我创建的一个方法,以克服这个问题,如果它可以帮助您:)

    public static decimal TruncateThenRound(decimal value, int? degits = 0, MidpointRounding? midpointRounding = MidpointRounding.ToEven)
        {
            var multiplier = Convert.ToDecimal(Math.Pow(10.0, degits.Value));
    
            var unwantedDecimals = (value * multiplier) - Math.Truncate(value * multiplier);
    
            var truncated = Math.Truncate(value * multiplier) / multiplier;
    
            bool roundUp = midpointRounding == MidpointRounding.ToEven ? Math.Truncate(unwantedDecimals * 10) > 5m : Math.Truncate(unwantedDecimals * 10) >= 5m;
    
            return roundUp ? truncated + (1 / multiplier) : truncated;
        }
    
    推荐文章