Двойное преобразование в строку отличается для .NET Framework и .NET Core

#c# #json.net #double #precision

#c# #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>
 

Код:

 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);
 

Вывод (targetFramework = netcoreapp3.1, без точек останова):

 .NET Core 3.1.4
0.4123736171722412
0.4123736171722412
0.4123736171722412
 

Вывод (targetFramework = netcoreapp3.1, с точками останова):

 .NET Core 3.1.4
0.4123736171722496
0.4123736171722496
0.4123736171722496
 

Вывод (targetFramework = net48, с / без точек останова):

 .NET Framework 4.8.4250.0
0.412373617172241
0.41237361717224119
0.412373617172241
 

Внутри нет другого кода Main(string[] args) Program.cs .
Я использую JetBrains Rider для запуска этого.
Как вы можете видеть, преобразование двойного в строку отличается в зависимости от

  • цель .Используется NET framework (.NET Framework 4.8 против .NET Core 3.1)
  • установлены ли точки останова в коде или нет
  • выполняется ли это с помощью консоли.Строка записи или Json.СЕТЕВОЙ сериализатор

Может кто-нибудь объяснить, почему это преобразование double в string настолько отличается в зависимости от множества факторов? Разве эта операция не должна быть четко определена или указана? Какие еще факторы существуют? Процессор или микроархитектура?

Комментарии:

1. Используете ли вы другую версию Json.NET ?

2. Я добавил .csproj для пояснения, я использую Newtonsoft. Оба раза пакет Json 12.0.3 NuGet.

Ответ №1:

Я считаю, что это из-за улучшений синтаксического анализа и форматирования с плавающей запятой в .NET Core 3.0.

Вы могли бы решить эту проблему, указав формат, например:

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