加法的十进制顺序会影响结果

时间:2011-06-02 23:09:26

标签: c# math decimal

我有一个使用小数执行大量计算的系统,偶尔会添加相同的数字,但会返回不同的结果,+ / - 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

差异很小,没有实际效果,但有人见过这样的事吗?我希望在添加相同的数字时,您总能获得相同的结果。

5 个答案:

答案 0 :(得分:8)

Numerical analysis的整个领域致力于研究这些影响以及如何避免它们。

要在汇总浮点数列表时产生最佳结果,首先排序从最小到最大的列表,然后按顺序添加它们。

答案 1 :(得分:3)

您可能会怀疑decimal类型对double的祸根免受影响 - 各地的用户。

但是because decimal has 28-29 digits of precision并且您的输入要求数据精度的29位数之和,您就在数据类型可以准确表示的最边缘。

答案 2 :(得分:3)

答案 3 :(得分:2)

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

答案 4 :(得分:0)

由于四舍五入,多个数的和的结果可能会根据它们求和的顺序而有所不同。这不会发生在数学中,但是在你的例子中计算总和的顺序很重要。 result += number;将结果汇总并存储在结果变量中。那时候一些精度会丢失。但是,如果我们以相同的顺序执行,它将始终产生相同的结果。

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

由于这一点,许多程序使用Bankers四舍五入产生更接近的结果。请知道精度总是丢失。无法在计算机存储器

中存储“准确”的浮点数

Rounding

Bankers Rounding