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