I see that, in C#, rounding a decimal
, by default, uses MidpointRounding.ToEven
. This is expected, and is what the C# spec dictates. However, given t
ToString()
by default formats according to the Culture
, not according to a computational aspect of the specification. Apparently the Culture
for your locale (and most, from the looks of it) expects rounding away from zero.
If you want different behavior, you can pass an IFormatProvider
in to ToString()
I thought the above, but you are correct that it always rounds away from zero no matter the Culture
.
As also linked by a comment on this answer, here (MS Docs) is official documentation on the behavior. Excerpting from the top of that linked page, and focusing on the last two list items:
Standard numeric format strings are used to format common numeric types. A standard numeric format string takes the form
Axx
, where:
A
is a single alphabetic character called the format specifier. Any numeric format string that contains more than one alphabetic character, including white space, is interpreted as a custom numeric format string. For more information, see Custom Numeric Format Strings.
xx
is an optional integer called the precision specifier. The precision specifier ranges from 0 to 99 and affects the number of digits in the result. Note that the precision specifier controls the number of digits in the string representation of a number. It does not round the number itself. To perform a rounding operation, use the Math.Ceiling, Math.Floor, or Math.Round method.When precision specifier controls the number of fractional digits in the result string, the result string reflects a number that is rounded to a representable result nearest to the infinitely precise result. If there are two equally near representable results:
On the .NET Framework and .NET Core up to .NET Core 2.0, the runtime selects the result with the greater least significant digit (that is, using MidpointRounding.AwayFromZero).
On .NET Core 2.1 and later, the runtime selects the result with an even least significant digit (that is, using MidpointRounding.ToEven).
As far as your question ---
Is there a good reason this is the case? Or is this just an inconsistency in the language?
--- the answer implied by the change in behavior from Framework to Core 2.1+ is possibly, "No, there was no good reason, so we (Microsoft) went ahead and made the runtime consistent with the language in .NET Core 2.1 and later."