.NET Framework 和 .NET Core 的双精度到字符串转换不同

mxs*_*cho 3 c# precision double json.net

项目文件:

<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>
Run Code Online (Sandbox Code Playgroud)

代码:

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);
Run Code Online (Sandbox Code Playgroud)

输出(TargetFramework = netcoreapp3.1,无断点):

.NET Core 3.1.4
0.4123736171722412
0.4123736171722412
0.4123736171722412
Run Code Online (Sandbox Code Playgroud)

输出(TargetFramework = netcoreapp3.1,带断点):

.NET Core 3.1.4
0.4123736171722496
0.4123736171722496
0.4123736171722496
Run Code Online (Sandbox Code Playgroud)

输出(TargetFramework = net48,有/没有断点):

.NET Framework 4.8.4250.0
0.412373617172241
0.41237361717224119
0.412373617172241
Run Code Online (Sandbox Code Playgroud)

Main(string[] args)里面没有其他代码Program.cs。我正在使用 JetBrains Rider 来运行它。正如您所看到的,双精度数到字符串的转换是不同的,具体取决于

  • 使用的目标 .NET 框架(.NET Framework 4.8 与 .NET Core 3.1)
  • 代码内是否设置断点
  • 无论是使用 Console.WriteLine 还是 Json.NET 序列化程序完成

有人可以解释为什么这种双精度到字符串的转换会因多种因素而如此不同吗?这个操作不应该被明确定义或指定吗?还有哪些其他因素?CPU还是微架构?

tym*_*tam 5

我相信这是因为.NET Core 3.0 中浮点解析和格式的改进

您可以通过指定格式来解决此问题,例如:

Console.WriteLine(d.ToString("G15"));
Run Code Online (Sandbox Code Playgroud)