Search code examples
c#json.netdoubleprecision

Double to string conversion different for .NET Framework and .NET Core


Project File:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>[see below]</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
    </ItemGroup>
</Project>

Code:

Console.WriteLine(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
var d = 0.41237361717224119D;
Console.WriteLine(d);
var json = Newtonsoft.Json.JsonConvert.SerializeObject(d);
Console.WriteLine(json);
d = Newtonsoft.Json.JsonConvert.DeserializeObject<double>(json);
Console.WriteLine(d);

Output (TargetFramework = netcoreapp3.1, without breakpoints):

.NET Core 3.1.4
0.4123736171722412
0.4123736171722412
0.4123736171722412

Output (TargetFramework = netcoreapp3.1, with breakpoints):

.NET Core 3.1.4
0.4123736171722496
0.4123736171722496
0.4123736171722496

Output (TargetFramework = net48, with/without breakpoints):

.NET Framework 4.8.4250.0
0.412373617172241
0.41237361717224119
0.412373617172241

There is no other code in Main(string[] args) inside Program.cs. I'm using JetBrains Rider to run this. As you can see, the double to string conversion is different, depending on

  • the target .NET framework used (.NET Framework 4.8 vs. .NET Core 3.1)
  • whether breakpoints are set within the code or not
  • whether it is done with Console.WriteLine or Json.NET serializer

Can someone explain why this double to string conversion is so different depending on so many factors? Shouldn't this operation be well-defined or specified? What other factors are there? CPU or microarchitecture?


Solution

  • I believe it's because of Floating-Point Parsing and Formatting improvements in .NET Core 3.0.

    You could address this by specifying the format, for example:

    Console.WriteLine(d.ToString("G15"));