Why does .NET decimal.ToString(string) round away from zero, apparently inconsistent with the language spec?

前端 未结 3 1623
一整个雨季
一整个雨季 2021-02-18 15:52

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

3条回答
  •  [愿得一人]
    2021-02-18 16:28

    If you read the spec carefully, you will see that there is no inconsistency here.

    Here's that paragraph again, with the important parts highlighted:

    The result of an operation on values of type decimal is that which would result from calculating an exact result (preserving scale, as defined for each operator) and then rounding to fit the representation. Results are rounded to the nearest representable value, and, when a result is equally close to two representable values, to the value that has an even number in the least significant digit position (this is known as “banker’s rounding”). A zero result always has a sign of 0 and a scale of 0.

    This part of the spec applies to arithmetic operations on decimal; string formatting is not one of those, and even if it were, it wouldn't matter because your examples are low-precision.

    To demonstrate the behaviour referred to in the spec, use the following code:

    Decimal d1 = 0.00000000000000000000000000090m;
    Decimal d2 = 0.00000000000000000000000000110m;
    
    // Prints: 0.0000000000000000000000000004 (rounds down)
    Console.WriteLine(d1 / 2);
    
    // Prints: 0.0000000000000000000000000006 (rounds up)
    Console.WriteLine(d2 / 2);
    

    That's all the spec is talking about. If the result of some calculation would exceed the precision limit of the decimal type (29 digits), banker's rounding is used to determine what the result will be.

提交回复
热议问题