Same code has different return value in .net Framework and .net Core

zhijieli

New member
Joined
Mar 7, 2022
Messages
3
Programming Experience
5-10
Hi All,

We are migrating some projects from .net Framework to .net Core and find that the same code have different return value, is there any comments or suggestion to mitigate such precision difference?

The same script run in LinqPad5 (.Net Framework) and LinqPad6 (.Net Core) is different:

Example1:
decimal digit = 0.7918552036199095022624434389M;
double digitD = (double)digit;
digitD.Dump();

Value in .Net Framework: 0.79185520361991
Value in .Net Core: 0.7918552036199096

Example 2:
double digitD = 0.7918552036199095022624434389;
digitD.ToString(CultureInfo.CurrentCulture).Dump();

Value in .Net Framework: 0.791855203619909
Value in .Net Core: 0.7918552036199095
 
That will result in the Double.ToString() method being called. That uses the "G" format specifier, which does appear to produce different results in .NET Framework and .NET Core. If you call ToString and provide your own format specifier then you can specify the number of decimal digits and get the same output. That said, I just tested a format specifier of "g50" in both and got output of "0.79185520361990958" in .NET Framework and "0.79185520361990957560749393451260402798652648925781" in .NET 6. "g17" produced "0.79185520361990958" in both.
 
Also interesting readings here related to the "G" numeric format:

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 .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).
from Standard numeric format strings

When used with a Double value, the "G17" format specifier ensures that the original Double value successfully round-trips. This is because Double is an IEEE 754-2008-compliant double-precision (binary64) floating-point number that gives up to 17 significant digits of precision. On .NET Framework, we recommend its use instead of the "R" format specifier, since in some cases "R" fails to successfully round-trip double-precision floating point values.
from Standard numeric format strings
 
Thanks for your information! How about the example 1, is there any method that support convert decimal to double with a format specifier?
 
is there any method that support convert decimal to double with a format specifier?
Of course not, because format specifiers relate specifically to text representations of numbers.
 
The issue is, as I have demonstrated, when converting the double value to a string. Everything you need is in post #2.

To be clear, you can't just let the system create the text output because the system works differently in each case. If that is a problem then you need to create the text yourself explicitly and I have already shown you how to do that.
 
Also, if you want to have that level of precision, stick with decimal. You already have a decimal. Why are you converting to double?
 
Back
Top Bottom