Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net core 3与版本2.2产生不同的浮点结果_C#_.net Core 3.1_.net Core 3.0_C# 8.0_.net Core 2.2 - Fatal编程技术网

C# .net core 3与版本2.2产生不同的浮点结果

C# .net core 3与版本2.2产生不同的浮点结果,c#,.net-core-3.1,.net-core-3.0,c#-8.0,.net-core-2.2,C#,.net Core 3.1,.net Core 3.0,C# 8.0,.net Core 2.2,下面是一段示例代码,其输出来自.NETCore2.2和3.1。它显示了基本浮点表达式a^b的不同计算结果 在本例中,我们计算1.9乘以3的幂。以前的.NET框架产生了正确的结果,但是.NETCore3.0和3.1产生了不同的结果 这是一个预期的变化吗?我们如何将金融计算代码迁移到新版本,同时保证数值计算仍然会产生相同的结果?(如果.NET也有一个十进制数学库就好了) .NET核心2.2 ---十进制--------- ---双重的---------- .NET核心3.1 ---十进制------

下面是一段示例代码,其输出来自.NETCore2.2和3.1。它显示了基本浮点表达式a^b的不同计算结果

在本例中,我们计算1.9乘以3的幂。以前的.NET框架产生了正确的结果,但是.NETCore3.0和3.1产生了不同的结果

这是一个预期的变化吗?我们如何将金融计算代码迁移到新版本,同时保证数值计算仍然会产生相同的结果?(如果.NET也有一个十进制数学库就好了)

.NET核心2.2

---十进制---------

---双重的----------

.NET核心3.1

---十进制---------

---双重的----------


NET内核在IEEE浮点合规性方面引入了许多新技术。其中之一是IEEE 754-2008格式符合性

在.NET Core 3.0之前,
ToString()
在内部将精度限制为“仅”15个位置,生成的字符串无法解析回原始字符串。问题的值相差一位

在.NET 4.7和.NET Core 3中,实际字节保持不变。在这两种情况下

BitConverter.GetBytes(d*d*d)
产生

85, 14, 45, 178, 157, 111, 27, 64
另一方面,
BitConverter.GetBytes(6.859)
产生:

86, 14, 45, 178, 157, 111, 27, 64
即使在.NET Core 3中,解析“6.859”也会生成第二个字节序列:

BitConverter.GetBytes(double.Parse("6.859"))
这是一个单位差异。旧行为生成的字符串无法解析回原始值

这种变化解释了这种差异:

ToString()、ToString(“G”)和ToString(“R”)现在将返回最短的可循环字符串。这可以确保用户最终得到默认情况下可以正常工作的东西

这就是为什么我们在处理浮点数时总是需要指定精度。在这种情况下也有改进:

对于采用精度的“G”格式说明符(例如G3),现在始终遵守精度说明符。对于精度小于15(含15)的double和精度小于6(含6)的float,这意味着您将获得与之前相同的字符串。对于大于该值的精度,您将得到许多有效数字

使用
ToString(“G15”)
生成
6.859
,而
ToString(“G16”)
生成
6.85899999999999
,它有16个小数位数


这提醒我们,在处理浮点数时,无论是比较还是格式化,我们都需要指定一个精度。

在.NET Core 3.1中有很多有记录的浮点数改进。请让这个问题更具可读性。原始值和预期值是什么?为什么预期值被认为是正确的?旧结果有一点错误。实际的双精度值是相同的,但旧的字符串格式化程序生成了一个以单个位“是”关闭的字符串。1.9^3正好是6.859。被接受的答案以及例子和链接帮助我解决了这个问题。
a * a * a      = 6.858999999999999
Math.Pow(a, b) = 6.858999999999999
BitConverter.GetBytes(d*d*d)
85, 14, 45, 178, 157, 111, 27, 64
86, 14, 45, 178, 157, 111, 27, 64
BitConverter.GetBytes(double.Parse("6.859"))