seegongsik
単語帳
工業数学

コンピュータは数を近似でしか知らない

コンピュータの浮動小数点の限界、マシンイプシロンと丸め蓄積、致命的相殺と条件数

これまで私たちは誤差が手法から来ると見てきました。刻みが大きすぎる、次数が低すぎる。しかしあらゆる手法の下には、もっと根本的な限界が横たわっています。コンピュータは実数を正確に保存できません。0.1 さえも。64ビット浮動小数点は約15〜16桁しか覚えず、残りは丸めて捨てます。普段この微小な誤差は埋もれて見えませんが、ほとんど等しい二数を引いたり、小さな誤差を百万回積んだり、答えが入力に敏感な問題(悪い条件数)に出会うと突然飛び出します。この講は数値解析の底、すなわちコンピュータが数を扱う仕方そのものと、そこから漏れる誤差を見つめます。前の講で見た丸め誤差の床の正体です。

数直線上の目盛りが、コンピュータが正確に保存できる数です。一見奇妙です。0付近は密で右へ行くほどまばら。浮動小数点は数を有効数字いくつかに指数を付けて書くからです。ちょうど科学的記数法のように。だから大きさが2倍になる(1オクターブ)たびに、隣り合う表現値の間隔もちょうど2倍になります。この最小間隔を ulp(units in the last place)と呼びます。x を動かすと大きい数ほど ulp が大きくなるのが見えます。大きい数は粗く、小さい数は細かく保存されるということです。すべての丸め誤差はここから始まります。

その間隔が実際どれほど小さいか、1 の近くで測りましょう。ε = 2k を 1 に足しながら k を少しずつ下げてください。あるとき 1+ε がただの 1 になります。足した ε が 1 の上の表現間隔の半分より小さくなると、最も近い表現値(1 自身)に丸められるからです。この境界がマシンイプシロン、float64 では 2⁻⁵² ≈ 2.2×10⁻¹⁶。約15〜16桁の有効数字にあたります。これは抽象論ではなく本物の計算です。コンピュータにとって 1 足すごく小さな数はただの 1 になり得ます。精度に床があるという最初の証拠です。

誤差ひとつは10⁻¹⁶程度なので無視してよさそうです。ところが 0.1 は二進法で割り切れないため、保存した瞬間にすでにごく小さな誤差を抱えています。それを一回足すたびに誤差も少しずつ積もります。スライダーで加算回数を増やしてください。真値 n/10 からのずれが着実に大きくなります。一回では見えなかったものが数百回で明らかになり、シミュレーションのように何十億回も繰り返す計算では結果を台無しにしかねません。だから数値プログラマは加える順序を変えたり(小さいものから)、補正付き加算(カハン加算)でこの蓄積を抑えます。

最も恐ろしいのは別にあります。ほとんど等しい二数を引くことです。(1−cos x)/x² を小さな x で計算してみましょう。真の値は x が小さくなるほど 0.5 へ向かうはずです。ところが金の曲線(素朴に計算)はあるとき0に崩れます。x が小さいと cos x がほぼ1なので、1−cos x が有効数字をほとんど失うからです。先頭の桁がそろって打ち消し合い、信用できない末尾だけが残ります。これが致命的相殺です。青の曲線は同じ値を 1−cos x = 2 sin²(x/2) と書き換えて計算したものです。引き算をしないので最後まで 0.5 を守ります。式は同じでも、計算の順序が精度を生かしも殺しもします。

最後は誤差ではなく、問題そのものの性質です。連立方程式を解くとは、二直線の交点を探すことです。二直線が気持ちよく交われば交点は鮮明です。ところがほとんど平行なら? 一方の直線を髪一筋ほど動かしても交点が遠くへ飛びます。スライダーで傾きを下げて二直線を平行に近づけてください。同じ10%の揺れで解がどんどん大きく動きます。この増幅率が条件数です。条件数が大きい(悪条件)と、入力の小さな誤差が答えで大きく膨らみます。恐ろしいのは、これは丸め誤差と違って良いコンピュータでも直せないこと。問題そのものが敏感だからです。だから良い数値解析は、安定なアルゴリズムとよく条件づけられた問題の両方を大切にします。

実際に使うコンピュータは実数を約15〜16桁の有効数字でしか保存しません。表現可能な数は0付近で密、大きいほどまばらで、間隔(ulp)はオクターブごとに2倍になります。1 と区別できる最小の数がマシンイプシロン(float64 ≈ 2.2×10⁻¹⁶)です。この微小な丸め誤差は普段は埋もれていますが、三つの状況で飛び出します。小さな誤差の蓄積(シミュレーション)、ほぼ等しい数の引き算による致命的相殺、そして入力に答えが敏感な悪い条件数。前の二つはアルゴリズムを安定に書き直して減らし(計算順序・等価な式)、条件数は問題そのものの性質なので良いコンピュータでも直せません。数値解析の二本柱がここから生まれます。安定な手法を選び、よく条件づけられた問題に作り変えること。これがあらゆる数値計算の底です。
工業数学
このページがお役に立ったなら支援する