浮動小数点 なぜ誤差が起こるのか

今更も今更、小数計算でなぜ誤差が起こるのか。そして、その対策って何すればいいのだろうかというお話です。

そもそも小数は「正確」に表現できていない。

まず、コンピュータは数字を二進数で保持しているかと思います。
たとえば、56だと

56 =  111000

となり、この導出としては「56から2で割り、商を2で割り続け、商が0になったら余りを降順にして並べる」というもの。

56 / 2  = 28 + 0
28 / 2  = 14 + 0
14 / 2  = 7 + 0
7 / 2 =  3 + 1
3 / 2 = 1 + 1
1 / 2= 0 + 1

ここまでは、イメージしやすいかと思います。
では、話を小数に戻しましょう。
そもそも、小数を二進数に置き換える処理ってどのような処理をはさんで行われるかご存知ですか(恥ずかしながら、エンジニアになるまで僕は知りませんでした)
その処理とは「小数部分を2をかけ続け、一の位を取り出しながら0になるまで繰り返していく」というもの。

0.875  * 2 = 1 + 0.750
0.750 * 2 = 1 + 0.500
0.500 * 2 = 1 + 0.000
* 一の位を昇順でとっていく。

となります。
きれいに111となりましたが、実は小数でこのようなきれいな値になるほうが稀有です。
0.1~0.9の中で(小数第一位まで)、このような値になるものは0.5のみとなります。
それ以外はすべて循環小数となっており、正確な値にはなっておらず、わずかながら誤差が生まれます。

上記の理由から、小数計算については正確さを求められる場合は慎重にならなくてはいけません。

対策としては、「文字」として分けて処理をする。

ここで、今のところ私がとっている対策としては、各桁を一文字ずつ計算していくという対応です。
*コードは別のコードに載せます。。。ここでは覚書のみとさせていただきます。