「コンピュータ計算の落とし穴」

博士(情報科学)
数値解析
早稲田大学理工学部情報学科を卒業後、同大学院理工学研究科情報科学専攻修士課程、博士課程を修了。その後、早稲田大学理工学部助手、客員講師などを経て、2010年よりサイバー大学IT総合学部に着任。
コンピュータ計算の落とし穴
みなさんの生活において、コンピュータによる作業は仕事や私生活でも欠かせないものになっているのではないでしょうか。その際、コンピュータは高速に正しい処理を行ってくれる機械であると思われている方も多いと思います。しかし、コンピュータ上で行われる計算に含まれる誤差の影響で、場合によっては予想もしないことが起きてしまいます。そのような現象を、具体的な例を用いて紹介します。
湾岸戦争での出来事
1990年代にあった湾岸戦争の際に起こった、次のような出来事があります。
1991年2月、サウジアラビアにおいて、イラク軍より発射されたスカッドミサイルを打ち落とすため、アメリカ軍がパトリオットミサイルを発射しました。しかし迎撃に失敗し、スカッドミサイルはアメリカ軍の基地を直撃しました。その結果、多数の死傷者がでました。
戦争自体、決して起きてはならないことなのですが、この出来事の裏には、コンピュータ上の計算における誤差が大きく関わっています。以下では、何が原因となっているかを説明します。
2進数
私たちは計算を行う際に、0 ~ 9 の10個の数字を用いる「10進数」を使用して数を表現しています。一方、コンピュータ上では通常、数は「10進数」ではなく「2進数」で表現します。「2進数」は 0 と 1 のみで数を表す表現方法です。
もう少し具体的に説明しましょう。
「10進数」では0 ~ 9 の10個の数字を用いて数を表現します。例えば、10進数の「1234」は、
1×103+2×102+3×101+4×100 となり、各桁の数に10のべき乗を掛けたものの和を計算することで表現できます。
「2進数」では 0 と 1 の2つの数字しか使いません。例えば、2進数で「1111」という数は、10進数の場合と同様に表現すると、 1×23+1×22+1×21+1×20 となります。これを計算すると「15」になります。つまり2進数の「1111」は10進数の「15」ということになります。
10進数と2進数の関係をまとめると次のようになります:

ふだん私たちが10進数として表現している数は、コンピュータ上で計算を行う場合には2進数に変換しなければなりません。この変換は上の関係から行うことができます。例えば、整数の場合、10進数の「21」は 16 + 4 + 1 ですので、2進数では 10000 + 100 + 1 = 10101 となります。
一方で、実数値の場合はどうなるでしょうか。10進数の「0.1」という値を考えてみます。上で示した対応関係から「0.1」を2進数で表現すると
コンピュータ上では無限に続く値をそのまま表現することはできません。どこかで打ち切って有限桁のデータとして表現しなければならないわけですが、その際に誤差が発生してしまいます。コンピュータ上で実数値を扱う際はほとんどの場合において誤差が含まれています。それは「0.1」といった10進数としてはシンプルな値でも例外ではありません。
浮動小数点数と誤差
では、コンピュータ上で実数はどのような形式で表現されているのでしょうか。また、数値に含まれる誤差が計算結果にどの程度影響するのでしょうか。ここではその表現形式について簡単に説明して、実際にどの程度の誤差が発生するのかを、サンプルのプログラムを使用して検証します。
多くのコンピュータでは、実数値の表現とその演算については IEEE754 という規格に基づいています。例えば、プログラミングで実数値を扱う場合に利用する「倍精度浮動小数点数(double型)」は1つの数値を表現するのに 8byte = 64bit の容量を使用します。そしてその表現形式は次のようになっています:

倍精度浮動小数点数(double型)を使用することでどの程度の誤差が含まれるかを、実際にプログラムを作成して確認してみましょう。例として、「0.1」を百万回足し合わせる計算を行います。当然ながら、正しい計算結果は

このように、double型を用いた計算では正確に「100000」とはならず、誤差が確認できます。double型の精度は15桁程度ありますので、1回の計算による誤差はごくわずかです。しかし、誤差を含んだ値を使用して計算を続けることにより、計算のたびに誤差が蓄積され、とんでもない結果を導くこともあります。
パトリオットミサイルのソフトウェア
冒頭で紹介した話題に戻りましょう。
コンピュータ上で2進数により実数を表現すると誤差が含まれ、それは「0.1」といった値でも例外ではないことを示してきました。当時のパトリオットミサイルの迎撃システムでは、時間の計測に「0.1」という値を使用していました。つまり、システムの起動から時間が経つにつれ誤差が蓄積され、ミサイル発射のタイミングがずれる結果となっていたのです。
先ほどの倍精度浮動小数点数では1つの数値を表現するのに64bitを使用しますが、当時のパトリオットミサイルのシステムでは24bitで1つの数値を表現していました。そのため、先ほど示した例よりもさらに精度は悪く、システムを100時間動かし続けることで誤差は約0.34秒に達していました。高速で移動するスカッドミサイルを打ち落とすために発射するパトリオットミサイルの発射のタイミングが0.34秒ずれると、その命中精度が高くないことは容易に想像がつきます。
今回は軍事関係の物騒な例を取り上げましたが、他の分野においても誤差を考慮した計算が必要な状況はたくさん存在します。科学技術の計算では厳密な結果を求められることが多いですし、製品の設計段階における誤差のために製品に影響を及ぼすことも考えられます。このような誤差の影響を考慮したコンピュータ上での厳密な計算を行うための研究も盛んに行われています。コンピュータでの計算は非常に高速で便利なものですが、計算による誤差の影響についても頭の片隅に入れておいてください。




















