先日、こんなことがあった。
78000.00000000000
という数字を使って計算すると末尾がおかしい!と逆上するエンジニア。
さて、どこが間違いでしょうか。最近の若いエンジニアにはわからないかもしれない。
ヒントは16桁。
コンピュータ内部では、一般的には数値は2進数で計算されるということは知ってると思います。
十進数は二進数に変換される。
で、正確に変換できない数値があるということを知ってますかね?
驚く人、知らない人はここでも読んでください。10分で大事な知識が手に入ります。
要するに浮動小数点演算の方法はIEEE 754で定義されていて、倍精度計算64ビット中で、符号が1ビット、指数部が11ビット、仮数部(数字を表す部分)に割り当てられているのが53ビット。
これで
2^52 = 4,503,599,627,370,496
2^53 = 9,007,199,254,740,992
が表現される。
つまり、浮動小数点演算の中で最も値2^-53以下の計算はできないので、これ以下が丸め誤差となるのです。丸め誤差で使われる最終値イプシロン値とは、ε を任意の正の数としたときの (1 + ε) – 1 となれる数字のことをいいます。
丸める方法はいろいろありますが、16桁あたりをうろうろする計算をすると誤差は生じます。
厳密なことは知らなくても、コンピュータの計算精度に限界があるくらいのことも認識していない、(自称)ITエンジニアを見ると、業界で知っていなければならないことを知らなくて、簡単に「製品が悪い」と叫び、無知をさらけだせるくらいの世の中になったんだな、と感無量でございます。
今時は、ITのプロって最低限の知識はなんなのでしょうか?
SOAやなんだかんだと叫んでも、最終的にはハードウェアが処理するし、ネットワークの遅延はなくなりません。これからさらに動かないシステムが増えるんだろうな。
中国製品と同じように安くてピカピカ(すごい機能をうたう)したものを買い込んで、すぐ壊れる。ひょっとしたら、最初から動かないかも知れない。
安物買いの銭失いは起きます。
ちなみにコンピューターで完全に十進数計算をシミュレーションして計算するBCD演算という方法があります。大昔からあります。これならば、精度が狂うことはありませんが、非常にリソースを食うので、計算は遅いというコストを払うことになります