为什么我通过重新排列术语的顺序得到不同的答案

时间:2016-09-17 05:08:43

标签: c

以下是C程序的片段。

有人可以告诉我为什么这两个语句给出不同的值,即使表达式在数学上是等价的:

printf("    WARNING: sum = %e   at   time index = %d\n",C[21]*X[0] + C[22]*X[1] + C[23]*X[2] + C[24]*X[3] + C[25]*X[4] + C[26]*X[5] + C[27]*X[6],TIME_INDEX);
printf("    WARNING: sum = %e   at   time index = %d\n",C[21]*X[0] + C[27]*X[6] + C[22]*X[1] + C[26]*X[5] + C[23]*X[2] + C[25]*X[4] + C[24]*X[3],TIME_INDEX);

这是打印输出

WARNING: sum = -5.551115e-17   at   time index = 1
WARNING: sum = 0.000000e+00   at   time index = 1

答案应该完全等于零。我不明白为什么这些条款的顺序在总结中很重要。

编辑:我应该说在制作印刷陈述之前我明确定义了X [0] = X [6],X [1] = X [5],X [2] = X [4]。 / p>

中心差异系数是 C [21] = -1.0 / 60.0; C [22] = 9.0 / 60.0; C [23] = -45.0 / 60.0; C [24] = 0.0 / 60.0; C [25] = 45.0 / 60.0; C [26] = -9.0 / 60.0; C [27] = 1.0 / 60.0;

1 个答案:

答案 0 :(得分:3)

案例不同,因为机器单独处理操作且精度有限。沿着该值的每一步舍入到最接近(尽可能跟踪)可用的表示。

在一种情况下,相同的术语完全取消,在另一种情况下,你可能有一个如此大的值,其中一个较小的术语无法完全应用。所以最终差异大约是6 * 10 ^ -17,或2 ^ -54;它与IEEE 754 64-bit floating point中有效的53位尾数匹配得很好。事实上,您的错误尽可能小。

请注意,这并不需要大数字,只有那些不能用可用宽度精确表示的二进制数字,例如/ 60值(1/3和1/5都需要无限大)二进制数字;也是十进制的1/3)。

这是正确理解numerical analysis的基础。您有时可以使用更合适的表示来缓解它,例如arbitrary precision (bignum)可以存储比处理器理解的值更大的值,或rational形式,当您的所有值都合理时。这就是为什么数据库往往具有单独的decimal类型。但是,每个人都有自己的极限;在这些例子中,只有1/60符合理性。