decimal.Round 的奇怪行为

Weird behaviour of decimal.Round

当使用decimal时,为什么四舍五入的行为总是一样的?

无论我是否使用MidpointRounding.AwayFromZero,它总是给出1.04。在第一种情况下,输出不应该是1.03吗?

Console.WriteLine(decimal.Round(1.035m, 2));
Console.WriteLine(decimal.Round(1.035m, 2, MidpointRounding.AwayFromZero));

https://github.com/dotnet/corefx/blob/664d98b3dc83a56e1e6454591c585cc6a8e19b78/src/Common/src/CoreLib/System/Decimal.cs#L612

https://github.com/dotnet/corefx/blob/61d792e202d039c304c4f04ad816a57688f32fd4/src/Common/src/CoreLib/System/Decimal.DecCalc.cs#L2429-L2444

No:

This method [Round(decimal d, int decimals)] is equivalent to calling the Round(Decimal, Int32, MidpointRounding) method with a mode argument of MidpointRounding.ToEven.

When d is exactly halfway between two rounded values, the result is the rounded value that has an even digit in the far right decimal position. For example, when rounded to two decimals, the value 2.345 becomes 2.34 and the value 2.355 becomes 2.36.

因此当 1.035 四舍五入为偶数时,它变成 1.04 因为 4 是偶数而 3 不是。

默认的四舍五入方式是MidpointRounding.ToEven,所以在选择四舍五入到1.03或者1.04的时候,选择最后的偶数,1.04.

正如 MSDN 所说:

public static decimal Round(
    decimal d,
    int decimals
)

decimals : A value from 0 to 28 that specifies the number of decimal places to round to.

你要在2处取整,必须是1.04

这对我来说似乎是四舍五入小数时的预期行为。

例如:

1.035 => 1.040 产生两位小数 1.04

1.033 => 1.030 产生两位小数 1.03

默认的四舍五入不是向上取整吗?在这种情况下,5 会被舍入并结转...

默认情况下,Round 方法使用四舍五入到最接近的约定。下面的 table 列出了 Round 方法的重载以及每个方法使用的舍入约定。 https://docs.microsoft.com/en-us/dotnet/api/system.math.round?view=netframework-4.7.2