2008年6月24日火曜日

数値誤差

日々是数値誤差との戦い。しょっちゅう、え、どうだったっけ?とか思うので自分用にまとめてみた。

コンピューター内部の数は浮動小数点数で扱われる。
浮動小数点数は1.24356*10^-2のように、符号部、仮数部、指数部に数字を分けて扱う。それぞれの部分はコンピューターの内部では当然2進もしくは16進であらわされる。倍精度実数の場合、符号部に1ビット、仮数部に52ビット、指数部に11ビットの合計64ビットが使われる。指数をもちいて表現することで、扱える数の幅が大きく広がる。
浮動小数点のフォーマットにはIEEE754やIBMのエクセス64とかがある。IEEEは指数の基数が2、エクセス64は基数が16である。モノの本によると基数2のほうが丸め誤差に強いとかなんとかいう噂。どっちが使われるかはコンパイラ次第。マイクロソフト系のVBAとかは基数2を使っているとの噂だがどうだろう。それ以外にも2つのフォーマットは仮数部に+1したりしなかったり、指数部のバイアスが違ってたり、いろいろ差異があるっぽい。

どっちのフォーマットを使おうが、数値計算の時に、めちゃ問題になるのが桁落ち、情報落ち、丸め誤差などなど。どれも浮動小数点数の特徴からでてくるので、数値計算のときにはどうしてもついてくる。全部ひっくるめて丸めとかround off errorとか書いちゃったりしている文献もある模様。

物理屋の計算で出くわしがちなのが桁落ちか。桁落ちは、値が非常に近い数を引き算したときに出てくる。
たとえば 1.1200012-1.1200003とかを計算すると、計算に使ってる値は有効数字6桁なのに、答えは0.000009の有効数字一桁とか精度ががた落ちする。浮動小数点数では、元の数も近似値なので、有効な桁数の低下はかなり問題。しかも、浮動小数点数では正規化の手続きがあって、これを、0.90000000*10-8のようにシフトするので、意味のない0が押し込まれてくる。ので、Lanczos法とかみたく、あるN回目の計算でN-1回目の結果を使って、みたいに再帰的な計算になっててしかも引き算がばりばり出てくるのは要注意。今つかってるのはLanczos法と似たようなアルゴリズムの計算なんだけど、再規格化とかしないと10回行かないうちに誤差の累積で破綻した。数値をダイレクトに使うだけじゃなく、規格直交条件とか数学方向から要請される条件を組み合わせて使うことが大事。

0 コメント: