Open yac073 opened 3 years ago
Hello. I can't seem to understand what the issue is. Can you give me a more detailed description of what you have and what you expected?
In MS page Standard numeric format strings, it claims that
On .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).
However, from the example I showed above, some standard formatting failed to use MidpointRounding.ToEven and are still using MidpointRounding.AwayFromZero.
@bartonjs @joperezr would either of you be able to answer this question?
cc @tannergooding
For 1 and 2, this is by design and expected. For 3 I was not able to reproduce the issue.
For 1 and 2, floating-point literals may not produce exactly the value specified. Instead, the language parses the literal and produces the nearest representable value as per the IEEE 754 rules.
In the case of the first scenario, 1234.5
is exactly representable and so the 5
is treated as a proper midpoint value.
However, in the second case 12.345
is not exactly representable and instead is internally 12.3450000000000006394884621840901672840118408203125
, which is the nearest representable value to exact literal given. This means that the 5
is not actually a midpoint value because the underlying represented value is actually over 12.345
and so will always round up.
Thanks for the clarification on 1 and 2. For 3 the screenshot of the sample program and csproj are these.
@tannergooding can you check this out again when you get a chance? Thanks!
I'm able to repro now. Thanks!
I need to dig deeper to determine if this is a product or doc bug. There are a few places where decimal
is handled differently and this might be "by design".
Thank you for the update. I assigned the issue to you so that it's on your radar 😄
Is there any update on this?
I am facing the same issue here, decimal is always rounded by MidpointRounding.AwayFromZero on .NET 6, which is contradict with the document (On .NET Core 2.1 and later, the runtime selects the result with an even least significant digit (that is, using MidpointRounding.ToEven).).
Just want to know if this is by design or a bug.
@tannergooding ping
Would it be better to open this issue in the .NET product repo instead of the docs repo?
There are some known bugs with Round
due to the underlying implementation (which has been around back into .NET Framework).
Scaling up, trying to round, and then scaling back down isn't "safe" and may introduce additional error that leads to incorrect rounding in various cases.
I won't be able to look more in depth at the additional feedback here until later.
[Enter feedback here] Tested on .net core runtime 3.1.10
double num = 1234.5; var str = num.ToString("G4"); (1234, the rounding is using MidpointRounding.ToEven which is the expected behavior)
double money = 12.345; var moneyStr = money .ToString("C"); ($12.35, the rounding is using MidpointRounding.AwayFromZero, the result is expected to be $12.34 since formatting should be using MidpointRounding.ToEven)
decimal num2 = 1234.5m; var str2 = num2.ToString("G4"); (1235, the rounding is using MidpointRounding.AwayFromZero, the result is expected to be 1234 since formatting should be using MidpointRounding.ToEven)
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.