10

我没有看到 Math.Round 的预期结果。

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

据我了解 MidpointRounding.ToEven,千分之一位置的 5 应该导致输出为 99.96。不是这样吗?

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

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

我错过了什么

谢谢!

4

8 回答 8

27

你实际上不在中点。MidpointRounding.ToEven表示如果您有数字99.965,即 99.96500000[等],那么您将获得 99.96。由于您传递给 Math.Round 的数字高于此中点,因此它正在向上取整。

如果您希望您的数字向下舍入到 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);
}
于 2009-09-14T18:12:20.893 回答
10

如果你在中点本身,它只会四舍五入到 99.96,即 99.965:

C:\temp>ipy
.NET 2.0.50727.4927 上的 IronPython 2.6 Beta 2 (2.6.0.20)
输入“帮助”、“版权”、“信用”或“许可”以获取更多信息。
>>> 导入 clr
>>> 从系统导入数学,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
>>>
于 2009-09-14T18:12:31.887 回答
5

MidpointRounding值仅在您尝试对最低有效位正好为 5 的值进行四舍五入时起作用。换句话说,该值必须是99.965获得您想要的结果。由于这里不是这种情况,因此您只是在观察标准的舍入机制。有关详细信息,请参阅MSDN 页面

于 2009-09-14T18:13:49.453 回答
4

以下是对这个主题有所启发的结果:

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。

于 2009-09-14T18:14:08.860 回答
0

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

这就是我要做的:

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

这更容易阅读,更像是一种数学方法。
我将数字乘以100,现在我有了9996.535789
然后将它与四舍五入截然不同,它返回最接近数字的最小整数,得到9996.
然后我除以100得到所需的99.96.

PS
Floor上限相反,它返回最接近数字的最大整数。
所以, 的上限9996.5357899997
两者都不同于四舍五入到无小数点,它实际上返回最接近数字的整数,无论​​它是更小还是更大——以最接近者为准;这就是为什么你在99.97使用rounding时得到的原因。

于 2010-11-20T00:26:46.223 回答
0

仅当值介于两种情况之间时,才会查看中点舍入。

在您的情况下,它不是“5”,而是“535 ...”,因此它大于中点,并且例程为 0.96。要获得您期望的行为,您需要截断到小数点后第三位,然后使用 MidpointRounding.ToEven 进行舍入。

于 2009-09-14T18:13:36.377 回答
0

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

于 2009-09-14T18:16:02.710 回答
0

感谢 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;
    }
于 2021-07-07T08:52:51.660 回答