パソコンで数値計算

桁落ち

数値計算させると有効桁数が変わる

手計算で有効桁数を意識するのは重要なことですが、数値計算においても有効桁数に気をつけなければならない場合があります。その1つが、桁落ちです。桁落ちとは、足し算、もしくは引き算を行ったときに出された結果が、非常に小さい値になるときに起こる現象であり、その後の数値計算処理次第では、大きな誤差につながりますので、ほぼ等しい数値を足し算したり、引き算をしたりするときは、注意が必要です。

実際に桁落ちが起こる簡単な例を紹介します。ここでは、1.0000001 から 1.0000000 を引き算し、その結果に 10 の 8 乗を掛けることを考えます。手計算で行えば、10 になることがわかりますが、コンピューターに数値計算させるとどうなるのでしょうか。以下に、上記の計算を行わせるソースコードを掲載します。
#include <stdio.h>
 
int main(void)
{
    float num1, num2;
    num1 = 1.0000001;
    num2 = 1.0000000;
 
    printf("num1=%1.8f\n", num1);
    printf("num2=%1.8f\n", num2);
 
    printf("(num1-num2)×10^8 = %f\n", (num1 - num2)*1e8);
 
    return 0;
}

数値計算実行結果

上記のプログラムをコンパイルし実行すると、以下のような結果が表示されます。
num1=1.00000012
num2=1.00000000
(num1-num2)×10^8 = 11.920929
1行目と2行目は、各数値の精度を確認するために表示させたものであり、特に num1 の場合は、コンピューターでは2進数で扱う結果生じる誤差が発生しているのが確認でき、小数点以下7桁まで精確であることがわかります。

3行目が最終的な数値計算結果なのですが、10 とは大きくずれた結果となってしまっています。これは、num1 - num2 の計算を行ったときに桁落ちが発生したことが原因であり、このときに有効桁数が1桁になってしまっています。つまり、コンピューターでは、0.1 × 10 の -6 乗のように扱われています。

この結果に 10 の 8 乗をすると、有効桁数より後の桁に見られる信頼できない値が、大きな誤差となって表れます。このように桁落ちが発生した後の数値計算処理によっては、大きな誤差が発生しますので、数値計算を行うときは、 ほぼ等しい数値を足し算したり、引き算をしたりする処理を避ける必要があります。そのためには、数値計算を処理させる順序を変更する等の工夫が必要です。

2009/09/20 更新