Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specific double to decimal conversion has unexpected result #110439

Closed
SitamMatt opened this issue Dec 5, 2024 · 3 comments
Closed

Specific double to decimal conversion has unexpected result #110439

SitamMatt opened this issue Dec 5, 2024 · 3 comments

Comments

@SitamMatt
Copy link

Description

When converting double value -802.05999999999949 to decimal, it is rounded automatically to -802.06. However given -802.059999, conversion is returing proper value.

Reproduction Steps

using System;

double source = -802.05999999999949;
decimal target =  (decimal)Convert.ChangeType(source, typeof(decimal));
decimal rounded = Math.Round(target, 6); 
Console.WriteLine(source);
Console.WriteLine(target);
Console.WriteLine(rounded);

double source2 = -802.059999;
decimal target2 =  (decimal)Convert.ChangeType(source2, typeof(decimal));
decimal rounded2 = Math.Round(target, 6); 
Console.WriteLine(source2);
Console.WriteLine(target2);
Console.WriteLine(rounded2);

Expected behavior

I think the conversion for -802.05999999999949 should return the value without any rounding.

Actual behavior

Returning value is rounded to second decimal place.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Dec 5, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

@tannergooding
Copy link
Member

This is effectively a duplicate of #72135

Noting that the correct decimal result is not -802.05999999999949m, but rather -802.0599999999994906829670072m, because the underlying value represented by the double -802.05999999999949 is actually -802.059999999999490682967007160186767578125 and decimal can track 28-29 decimal digits.

The basic issue here is that the decimal->double and double->decimal conversions are "flawed" (and have always been that way) and presume that double only has 15 significant digits of precision, when in actuality its you need no more than 17 significant digits to guarantee roundtripping but the actual value may have up to 1074 digits (767 significant digits).

This is a relatively low priority issue to fix and is a breaking change for something that has always behaved a particular way. Fixing it is likely to cause other issues and complaints downstream (likely more than one off cases like the above where the result appears to lose precision, because in practice the hidden precision will become more visible instead and lead users to raise more questions/issues).

@tannergooding
Copy link
Member

Going to close this as a duplicate and track an eventual fix against the original issue. But happy to answer any other questions on the topic here

@tannergooding tannergooding closed this as not planned Won't fix, can't repro, duplicate, stale Dec 5, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants