数値解析 第1回 (4) 誤差の発生メカニズム

 このページでは、コンピュータが誤差を産み出す原因をいくつか紹介します。

1. 丸め誤差

 C言語や Java などのプログラミング言語で実数を表すデータ型には float 型と double 型があり、 多くの処理系で float 型は 4 バイトデータ、double 型は 8 バイトデータです。 IEEE規格 ( IEEE754 ) における double 型 8 バイト ( = 64 ビット )の内訳は
  • 符号 : 1 ビット
  • 指数部 : 11 ビット
  • 仮数部 : 52 ビット
です。
 64ビットのデータは何通りありますか?
答え  $2^{64} = 18446744073709551616$ 通り。
 本当は無限個存在する実数を、 コンピュータ上ではこの有限通りのどれかに当てはめて表現しますので必然的に誤差を生じます。 これを「丸め誤差」と呼びます。 「丸める」の英語は round、10 進数なら四捨五入のことで、Excel の関数にもありましたね。

2. オーバーフロー・アンダーフロー

  • 表現できる最大の数を超えてしまうエラーをオーバーフローと言います。
  • 表現できる最小の数を下回って 0 に置き換えられてしまう現象をアンダーフローと言います。
float 型、double 型のオーバーフローはプログラムがエラー表示を出してくれますのでまだましです。 アンダーフローや、int 型のオーバーフローは気付かないところで起こっても そのまま実行し続けるのでタチが悪いです。

3. 累積誤差

 いわゆる「塵も積もれば山となる」というやつです。

4. 積み残し

 絶対値が大きく異なる2つの数を足したり引いたりすると、 小さい方の数の下位の桁が無視される現象です。
 例えば、ともに有効数字が5桁のふたつの数 $x=1.2345$ と $y=0.0056789$ を足すとき、 $x$ は最大で $5 \times 10^{-5}$ の絶対誤差を持っていますので、 $y$ の下位3桁は書いても意味がない、ということです。
$\begin{array}{cl} &1.2345 \\ +&0.0056789 \\ \hline &1.2402\\ \end{array}$

5. 桁落ち

 値の近いふたつの数を引くと、有効数字の桁数が減ってしまう現象です。例えば
$\begin{array}{cr} &\sqrt{10}=3.1622 \\ -&\pi=3.1416 \\ \hline &0.0202\\ \end{array}$