Windows .NET 更新后最后一位数字的舍入发生变化
Rounding of last digit changes after Windows .NET update
在 Windows 更新后,一些计算值的最后一位发生了变化,例如从 -0.0776529085243926 到 -0.0776529085243925。变化总是减一,偶数和奇数都会受到影响。这似乎与 KB4486153 有关,因为还原此更新会将值更改回以前的值。
在 Visual Studio 中调试并将鼠标悬停在变量上时,可以看到此更改。该值稍后被写入输出文件并在其中进行更改(没有 运行 调试器)。
最小可重现示例
var output = -0.07765290852439255;
Trace.WriteLine(output); // This printout changes with the update.
var dictionary = new Dictionary<int, double>();
dictionary[0] = output; // Hover over dictionary to see the change in debug mode
背景
计算值来自
output[date] = input[date] / input[previousDate] - 1;
忽略浮点运算精度的损失,我可以在Immediate中进行计算window并在升级前后得到-0.07765290852439255
。
但是,当鼠标悬停在 output
变量上时,我看到
{[2011-01-12 00:00:00, -0.0776529085243926]}
升级前和
{[2011-01-12 00:00:00, -0.0776529085243925]}
之后,此差异也会传播到输出文件。
更新前后计算出来的值好像是一样的,只是四舍五入不同而已
输入值为
{[2011-01-11 00:00:00, 0.983561000400506]}
{[2011-01-12 00:00:00, 0.907184628008246]}
目标框架设置为.NET Framework 4.6.1
问题
我可以做些什么来在保持更新的同时获得以前的行为吗?
我知道浮点计算中的精度损失,但为什么更新后会发生这种变化,我们如何保证未来的更新不会改变值的表示形式?
KB4486153 是 Microsoft .NET Framework 4.8 的更新,请参阅 https://support.microsoft.com/en-us/help/4486153/microsoft-net-framework-4-8-on-windows-10-version-1709-windows-10-vers
OP 遇到了浮点数学的常见问题之一。对于新软件,人们想要一致的答案还是最佳答案? (升级更好)
一些有助于推进问题的信息。
var output = -0.07765290852439255;
使用常见的 binary64 编码1,由于 binary64 的二进制性质,output
采用 exact
的值
-0.077652908524392 54987160666132695041596889495849609375
下面显示了前一个和下一个可能的 double
作为十六进制和十进制 FP。
-0.077652908524392 5
-0x1.3e10f9e8d3217p-4 -0.077652908524392 53599381885351249366067349910736083984375
-0x1.3e10f9e8d3218p-4 -0.077652908524392 54987160666132695041596889495849609375
-0.077652908524392 55
-0x1.3e10f9e8d3219p-4 -0.077652908524392 56374939446914140717126429080963134765625
-0.077652908524392 6
-0.077652908524392 55
(其编码与 -0.077652908524392 5498...
完全相同)的最佳四舍五入到最接近的值然后少一位是 -0.077652908524392 5
。升级后,代码打印出更好的答案 - 至少在这种情况下是这样。
我不认为这是一个四舍五入的变化,而是对文本转换的改进。
Is there something I can do to get the previous behaviour while keeping the updates?
也许吧,但看起来更新后的结果更好。
how can we guarantee that future updates don't change the representation of values
使用十六进制浮点输出(与 C 中的 "%a"
一样)是获得收益的一种方法不改变表示,但非十进制输出不熟悉.
1 对于其他编码,确切值可能比 -0.077652908524392 5
.
更接近 -0.077652908524392 6
在 Windows 更新后,一些计算值的最后一位发生了变化,例如从 -0.0776529085243926 到 -0.0776529085243925。变化总是减一,偶数和奇数都会受到影响。这似乎与 KB4486153 有关,因为还原此更新会将值更改回以前的值。
在 Visual Studio 中调试并将鼠标悬停在变量上时,可以看到此更改。该值稍后被写入输出文件并在其中进行更改(没有 运行 调试器)。
最小可重现示例
var output = -0.07765290852439255;
Trace.WriteLine(output); // This printout changes with the update.
var dictionary = new Dictionary<int, double>();
dictionary[0] = output; // Hover over dictionary to see the change in debug mode
背景
计算值来自
output[date] = input[date] / input[previousDate] - 1;
忽略浮点运算精度的损失,我可以在Immediate中进行计算window并在升级前后得到-0.07765290852439255
。
但是,当鼠标悬停在 output
变量上时,我看到
{[2011-01-12 00:00:00, -0.0776529085243926]}
升级前和
{[2011-01-12 00:00:00, -0.0776529085243925]}
之后,此差异也会传播到输出文件。
更新前后计算出来的值好像是一样的,只是四舍五入不同而已
输入值为
{[2011-01-11 00:00:00, 0.983561000400506]}
{[2011-01-12 00:00:00, 0.907184628008246]}
目标框架设置为.NET Framework 4.6.1
问题
我可以做些什么来在保持更新的同时获得以前的行为吗?
我知道浮点计算中的精度损失,但为什么更新后会发生这种变化,我们如何保证未来的更新不会改变值的表示形式?
KB4486153 是 Microsoft .NET Framework 4.8 的更新,请参阅 https://support.microsoft.com/en-us/help/4486153/microsoft-net-framework-4-8-on-windows-10-version-1709-windows-10-vers
OP 遇到了浮点数学的常见问题之一。对于新软件,人们想要一致的答案还是最佳答案? (升级更好)
一些有助于推进问题的信息。
var output = -0.07765290852439255;
使用常见的 binary64 编码1,由于 binary64 的二进制性质,output
采用 exact
-0.077652908524392 54987160666132695041596889495849609375
下面显示了前一个和下一个可能的 double
作为十六进制和十进制 FP。
-0.077652908524392 5
-0x1.3e10f9e8d3217p-4 -0.077652908524392 53599381885351249366067349910736083984375
-0x1.3e10f9e8d3218p-4 -0.077652908524392 54987160666132695041596889495849609375
-0.077652908524392 55
-0x1.3e10f9e8d3219p-4 -0.077652908524392 56374939446914140717126429080963134765625
-0.077652908524392 6
-0.077652908524392 55
(其编码与 -0.077652908524392 5498...
完全相同)的最佳四舍五入到最接近的值然后少一位是 -0.077652908524392 5
。升级后,代码打印出更好的答案 - 至少在这种情况下是这样。
我不认为这是一个四舍五入的变化,而是对文本转换的改进。
Is there something I can do to get the previous behaviour while keeping the updates?
也许吧,但看起来更新后的结果更好。
how can we guarantee that future updates don't change the representation of values
使用十六进制浮点输出(与 C 中的 "%a"
一样)是获得收益的一种方法不改变表示,但非十进制输出不熟悉.
1 对于其他编码,确切值可能比 -0.077652908524392 5
.
-0.077652908524392 6