プログラムでの小数計算で誤差を含んでしまう原因と解決方法
Perlに限らずだいたいのプログラムでは小数点の扱いが苦手。
なぜなら浮動小数点方式というデータの持ち方をしているから。
10進数の0.1を浮動小数点方式では正確に表現出来ない(循環小数となり、途中で丸められてしまう)
そのため近似値で扱うことになり、計算結果に誤差を含むケースが出てくる。
コチラの記事が分かり易かった
では誤差を少なく計算するにはどうするか、、
これも完璧ではないようだけど、桁を上げて(揃えて)整数として計算して
最後に桁を戻すような「仮想小数点方式」で計算するのが良いらしい。
0.1 + 0.7
という計算をしたかったら
( (0.1 * 10) + (0.7 * 10) ) / 10
こうするのが「仮想小数点方式」
■ジャストアイデアだけど
仮想小数点方式でも誤差を含むっていうのは
結局0.1のような小数を使って「計算」をするから。
それなら
小数値を文字として扱って桁上げしたらいいんじゃないかと。
正規表現とかで頑張って、、、
=> 実際JavaのBigDecimalとかはそれっぽいことしてるらしい。気が向いたら調べよう。
■COBOLは小数点の計算に誤差を含まない
金融系のシステムに採用されていたりするCOBOLは小数の計算に誤差を含まない。
そんな話を昔聞いたなーっと思ったので、どうやっているか調べてみた。
BCD(Binary-coded decimal) というデータの持ち方を採用しているらしい。
詳しくはコチラの記事が大変参考になった。
ここで紹介されているパック10進数形式というのをCOBOLでは採用しているらしい。
0.1のような小数は
浮動小数点だと近似値となるけど、
BCDなら正確に表現出来る。
■まとめ
誤差を含まず「仮想小数点方式」で計算すれば、面倒だけど他の言語でも誤差を無くせるという事でいいのかな。