警戒位
如果说一个许多步骤计算的最终结果可以安全地舍入到 N 位小数,那么,最终的舍入操作引入的舍入误差对整体不确定性的影响可以忽略不计。
然而,在中间步骤舍入到同样多的位数很可能是不安全的。 因为舍入误差可以累积。 如果中间步骤中用了 M 位小数,那么就有 M−N 个警戒位。
在多数计算系统中,浮点运算都会用到警戒位。例如 我们必须对齐它们的位数。也就是说我们必须向第一个操作数额外添加一位,即警戒位。 因此我们有 ,计算可得 或 . 如果不用警戒位的话,就是 ,计算得到 或 。产生了100%的相对误差。由此可见警戒位的重要性。
以下一段 C 代码说明了一个由浮点舍入导致的错误:
int main(){
double a;
int i;
a = 0.2;
a += 0.1;
a -= 0.3;
for(i = 0; a < 1.0; i++)
a += a;
printf("i=%d, a=%f\n", i, a);
return 0;
}
看上去程序不会终止。 然而输出是 :
i=54, a=1.000000
另一个例子是:
给定2个数字: 和 。我们使第一个数字中 的幂次和第二个数字一致,即:。那么两个数字的加和是:
0.0256*10^2 2.3400*10^2 + ____________ 2.3656*10^2
第二个数( )在填充两个 之后,后面的位数即警戒位,再后面的是舍入位。 舍入之后的结果是 而非 ,如果没有多余的位(警戒位和舍入位)的话,即仅考虑 。误差是 。
参考文献
- Forman S. Acton. Numerical Methods that Work, The Mathematical Association of America (August 1997).
- Higham, Nicholas J. Accuracy and Stability of Numerical Algorithms, Washington D.C.: Society for Industrial & Applied Mathematics, 2002.