加法的小数顺序会影响结果

本文关键字:影响 结果 顺序 小数 | 更新日期: 2023-09-27 17:58:22

我有一个使用小数进行大量计算的系统,偶尔它会将相同的数字相加,但返回不同的结果,+/-0.000000000000000000000000001

下面是一个简短的例子:

decimal a = 2.016879990455473621256359079m;
decimal b = 0.8401819425625631128956517177m;
decimal c = 0.4507062854741283043456903406m;
decimal d = 6.7922317815078349615022988627m;
decimal result1 = a + b + c + d;
decimal result2 = a + d + c + b;
Console.WriteLine((result1 == result2) ? "Same" : "DIFFERENT");
Console.WriteLine(result1);
Console.WriteLine(result2);

输出:

DIFFERENT
10.100000000000000000000000000
10.100000000000000000000000001

差异如此之小,以至于没有实际效果,但以前有人见过这样的事情吗?我原以为,当把同样的数字加起来时,你总是会得到同样的结果。

加法的小数顺序会影响结果

数值分析的整个领域都致力于研究这些影响以及如何避免它们。

要在对浮点数列表求和时产生最佳结果,请先将列表从最小到最大排序,然后按该顺序相加。

您可能怀疑decimal类型对double用户的危害免疫。

但是,由于decimal的精度为28-29位,而您的输入要求的是29位数据精度的总和,因此您正处于数据类型所能准确表示的边缘。

阅读《浮点指南》、《浮点运算:问题和局限性》,当然还有每一位计算机科学家应该知道的关于浮点运算的知识。啊,还有如何对付那些学会了在浮点数学中出现舍入错误的人。。

根据MSDN,小数的精度为28-29位。你的数字中至少有一个是29位,所以你很可能超过了限制。

由于四舍五入,多个数字的求和结果可能会因求和顺序而异。这在数学中不会发生,但在你的例子中,求和的方式——顺序很重要。CCD_ 4求和并将结果存储在结果变量中。在那个时候,一些精度就丧失了。然而,如果我们按照同样的顺序来做,结果总是一样的。

Console.WriteLine(numbers.Sum()); // Always returns 9.214085249270111332166335344

正因为如此,许多程序使用Bankers四舍五入,从而产生更接近的结果。请知道精度总是会丢失。没有办法在计算机存储器中存储"准确"的浮点数

舍入

银行四舍五入