4

I have two values like below,

V1 = 44194.291666666664 and v2 = 44193.

Below operations returns different values in .NETCore and .Framework

Product results Arithmetic operation : (v1 - v2) ToString() (v1 - v2).ToString()
.NET5.0 result 1.2916666666642413 "1.2916666666642413"
.NETFramework result 1.2916666666642414 "1.29166666666424"

Code snippet

        double v1 = 44194.291666666664;
        double v2 = 44193;

        double value = v1 - v2;
        string output = (v1 - v2).ToString();
  • 2
    MSDN doc doesn't seem to have remark to this, still says it will print 15 digits and not all 17. https://learn.microsoft.com/en-us/dotnet/api/system.double.tostring?view=net-5.0 `By default, the return value only contains 15 digits of precision although a maximum of 17 digits is maintained internally.` - use `.ToString("G15")` if you rely on it to be identically – Rand Random Dec 28 '20 at 13:27
  • Try compiling both in release mode and see if they give the same result – xanatos Dec 28 '20 at 13:27
  • Looks like it might be the 80-bit to 64-bit rounding issue. Are the both `double`s? What CPU and architecture (x86/x64) do you have? – Charlieface Dec 28 '20 at 13:28
  • @Charlieface The 80 and 64-bit numbers seem consistent https://dotnetfiddle.net/SYMd3L – mjwills Dec 28 '20 at 13:30
  • 3
    Seems like a bug to me this line https://github.com/dotnet/runtime/blob/c142f162854185ba45f0fab678f8b28d1add3968/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs#L532 doesn't return `'\0'` so it doesn't enter this if https://github.com/dotnet/runtime/blob/c142f162854185ba45f0fab678f8b28d1add3968/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs#L535 - IMHO report an issue here https://github.com/dotnet/runtime/issues – Rand Random Dec 28 '20 at 13:40
  • @Charlieface Yes both are double values. – priya nandhini Dec 29 '20 at 12:44
  • Created an issue on github on your behalf: https://github.com/dotnet/runtime/issues/46670 – Rand Random Jan 07 '21 at 14:38
  • 1
    Many existing questions about this. Project > Properties > Build tab, untick "Prefer 32-bit" in the .NETFramework project to get the same value as the .NET5 project. 32-bit projects use legacy 8087 floating point instructions, they calculate with increased intermediate 80-bit precision. The 64-bit jitter use the solution that Intel provided for these consistency problems, generating SSE instructions that don't extend precision. Note how .NET5 project default to x64, thus the difference you observed. [Backgrounder](https://stackoverflow.com/a/14865279/17034). – Hans Passant Jan 07 '21 at 15:25
  • @HansPassant - the duplicate issue doesn't fit at all – Rand Random Jan 07 '21 at 17:36

1 Answers1

1

This is (likely) by design as of .NET Core 3.0. See this blog post on the change: https://devblogs.microsoft.com/dotnet/floating-point-parsing-and-formatting-improvements-in-net-core-3-0/