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

拜拜、爱过 提交于 2019-12-03 22:43:11

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. Check the links in the comments for proof.

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.

Most likely because this is the standard way of dealing with currency. The impetus for the creation of decimal was that floating point does a poor job of dealing with currency values, so you would expect it's rules to be more aligned with accounting standards than mathematical correctness.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!