數值計算的可靠性(一)

黃志斌發表於2019-07-16

考慮數列:a0 = 1 - 1/e, an = 1 - nan-1 (n > 0)

其中 e 是自然對數的底。求 a999 的近似值。

提示:1 > a0 > a1 > a2 > a3 > ... > 0 。


我們使用以下 C 語言程式來計算 a999 的近似值:

#include <stdio.h>
#include <math.h>

int main(void)
{
  double v = 1 - 1 / M_E;
  for (int i = 1; i <= 1000; v = 1 - i++ * v)
    if (i < 5 || (i > 15 && i < 23) || i > 998)
      printf("a(%3d): %16.12lf\n", i - 1, v);
}

執行結果如下所示:

a(  0):   0.632120558829
a(  1):   0.367879441171
a(  2):   0.264241117657
a(  3):   0.207276647029
a( 15):   0.059033793642
a( 16):   0.055459301730
a( 17):   0.057191870597
a( 18):  -0.029453670752
a( 19):   1.559619744279
a( 20): -30.192394885584
a( 21): 635.040292597259
a(998):             -inf
a(999):              inf

可以看出,從 a17 開始的值肯定是錯誤的,這是由於雙精度浮點數的精度是是有限的,而兩個非常相近的浮點數相減,得到的結果只有很少幾位有效數字,造成了很大的數值誤差。

>> 接下篇

相關文章