數值計算的誤差來源

幾個數值誤差的例子

我們可以拿起計算機,鍵入7除以3,以 iPhone 為例,得到的答案是2.33333333 。若鍵入8 除以3,得到的答案是2.66666667。我們都只到不論是7/3 或是8/3 在理論上都是無限循環的小數。然而,在機器的世界裡無法用無窮記憶體的方式來儲存這無限循環小數,現實上我們是以有限的數字表達來近似計算的結果,使用有限數字來表達也是一種比較有效率的作法。從這個例子我們可以看到,用數位的數字儲存實數有所謂的位元數的問題,亦即我們用多少記憶體的量來儲存數字。當然位元數越高,能表示的數字就越精準。

問:上述兩個例子的最後一個數字,為什麼一個是循環小數的3,另外一個卻不是?

第二個例子,假設有一個一元二次方程式\(0.2 x^2 -47.91 x + 6 = 0 \)。若我們有一個十個十進位的計算機,那麼利用公式解我們得到的兩個值分別是\(0.1253003555\) 以及 \(239.4256996\) ,這裡指的十個十進位的表示法是不算頭與尾多出來的0 的部分,所以從較小的解的1數到最後的5 以及從較大的解的2 數到6,都剛好有十個數字。倘若我們現在換一個只有四個十進位的計算機,那麼用公式解我們可以得到

\begin{equation*} \frac{47.91\pm \sqrt{47.91^2-4\times 0.2\times 6}}{2\times 0.2}=\frac{47.91\pm \sqrt{2295-4.8}}{0.4}\\ =\frac{47.91\pm \sqrt{2290}}{0.4}\\ =\frac{47.91\pm 47.85}{0.4} \end{equation*}

 

我們可以得到兩個解,一個是239.4 與0.15。值得注意的是,從十個十進位的計算機降到四個十進位的計算機,在較大的解上,我們感覺誤差並沒有太大。然而在較小的解上,我們看到0.125 到 0.15,這裡有將近20% 的相對誤差出現((0.15-0.125)/0.125)。我們將對應較小解的公式改寫成

\begin{equation*} \frac{-b-\sqrt{b^2-4ac}}{2a} = \frac{2c}{-b+\sqrt{b^2-4ac}} \end{equation*}

我們可以看到由於b 的值是-47.91,帶入等號左邊的式子會出現兩個很靠近的數字(47.91 與47.85) 相減的情況,然而在等號右邊的式子,我們得到的是\(\frac{2\times 6}{47.91+47.85} = \frac{12}{95.76}=0.1253\),這個結果與原本十個十進位的計算機所計算出來的結果就相當,大幅減少了因為位元損失所帶來的誤差。從這個例子我們看見,同樣的公式內涵,不同的計算方式會得到不同的結果。

問:是什麼原因造成這樣的結果?