コンピュータが計算間違いをすることがあるということ、具体的にどのような計算間違いをし、
そこから、人間が使っている十進数とコンピュータが使う二進数の違いについて解説する。
(1) 【整数を二進数に置き換える方法】
例えば、10 を二進数に置き換える場合、次のようになる。
2)  
10
2)   5 余り 0 10 ÷ 2 = 5 … 0
2)   2 余り 1 5 ÷ 2 = 2 … 1
1 余り 0 2 ÷ 2 = 1 … 0
整数 10 は二進数では、
1 0 1 0
これを十進数に戻すと、
1 x 8 + 0 x 4 + 1 x 2 + 0 x 1 = 10
= 10
(2) 【小数点を含む数を二進数に置き換える方法】
今度は逆に、二進数の小数点を含む場合について、例えば、
0. 1 0 1 0
これは十進数では、
1 x 1 + 0 x 1 + 1 x 1 + 0 x 1
2 4 8 16
= 1 x 0.5 + 0 x 0.25 + 1 x 0.125 + 0 x 0.0625
= 0.625
となる。
例えば、0.3125 を二進数に置き換える場合、次のようになる。
0.3125 x 2 = 0.625 1の位 0
0.625 x 2 = 1.25 1の位 1 以下 1 の位を引く
0.25 x 2 = 0.5 1の位 0
0.5 x 2 = 1.0 1の位 1 小数点以下が 0 になったので、ここで終わり
小数点を含む数 0.3125 は二進数では、
0. 0 1 0 1
となる。
(3) コンピュータの計算の誤りについて考えてみたい。
CPU では、全ての処理を 0 と 1 で表し、計算なども 0 と 1 のみで処理をしている。
つまり、CPU の中では二進数が使われていて、十進数の計算では全ての数字は二進数に置き換え、
それから計算をしていることになる。
そこで、簡単な小数点を含む数で確認してみたい。
0.1 を二進数に置き換えると、
0.1 x 2 = 0.2 1の位 0
0.2 x 2 = 0.4 1の位 0
0.4 x 2 = 0.8 1の位 0
0.8 x 2 = 1.6 1の位 1 以下 1 の位を引く
0.6 x 2 = 1.2 1の位 1 以下 1 の位を引く
0.2 x 2 = 0.4 1の位 0
0.4 x 2 = 0.8 1の位 0
0.8 x 2 = 1.6 1の位 1 以下 1 の位を引く
0.6 x 2 = 1.2 1の位 1 以下 1 の位を引く
以下繰り返しになる
結果は、
0. 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0
となり、無限小数(とくに循環小数)となる。
同様に、0.2 を二進数に置き換えると、
0.2 x 2 = 0.4 1の位 0
0.4 x 2 = 0.8 1の位 0
0.8 x 2 = 1.6 1の位 1 以下 1 の位を引く
0.6 x 2 = 1.2 1の位 1 以下 1 の位を引く
0.2 x 2 = 0.4 1の位 0
0.4 x 2 = 0.8 1の位 0
0.8 x 2 = 1.6 1の位 1 以下 1 の位を引く
0.6 x 2 = 1.2 1の位 1 以下 1 の位を引く
以下繰り返しになる
結果は、
0. 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1
となり、無限小数(循環小数)となる。
このように、十進数では有限小数が二進数では無限小数となってしまうことがある。
そこで 0.1 + 0.2 をコンピュータで計算させるとすると、以上の無限小数を足し合わせる必要がある。
また、コンピュータでは計算できる桁数が決められていて、無限小数はある桁数までしか入れられない。
この決められた桁数は 52 桁で、それ以下の桁については十進数での四捨五入と同様に扱うことになる。
つまり 53 桁以降の数が 1 より大きければ切り上げ、1 よりも小さければ切り捨てるようにする。
(4) 二進数による計算の誤差はこのような表しきれない数によるもの?
図1 に示した様に 0.1 は [1] のようになり、0.2 は [2] のようになる。
なお、□で囲った部分がコンピュータが計算で利用する部分で、小数点以下の左から 0 を除いて、
最初の 1 の次の桁から初めて 52 桁の 0 と 1 の並びで、53 桁目以下の数により切り上げ切り捨てを
したものになる。この切り上げるまたは切り捨てるの処理のことを「丸める」という。
2 の〜乗 -54 -55 -56 -57
[1] 0.1
の二進数
丸め前 0 0 1 1 -57乗以降が53桁以下で
丸め後 0 1 0 - 丸めの対照になる。
[2] 0.2
の二進数
丸め前 0 1 1 0 -56乗以降が53桁以下で
丸め後 1 0 - - 丸めの対照になる。
そして、[3] は上記の 0.1 と 0.2 を夫々に丸めた後に足した二進数の値である。
また、[4] は 0.3 を上記の方法により、二進数に置き換えたものである。
2 の〜乗 -52 -53 -54 -55
[3] 0.1 + 0.2
の二進数
丸め前 0 1 1 1 上記の 0.1 と 0.2 の丸め後
丸め後 1 0 0 - の数を足し合わせたもの。
[4] 0.3
の二進数
丸め前 0 1 1 0 -55乗以降が53桁以下で
丸め後 0 1 1 - 丸めの対照になる。
したがって、コンピュータで 0.3 と 0.1 + 0.2 には違いがあることになり、その差は、
図1 の a の部分が 0 から 1 となり、0.1 + 0.2 が 0.3 より大きくなっている。
また、b と c の部分が 1 から 0 となり、0.1 + 0.2 が 0.3 よりも小さくなっている。
よって、
1 x 1 - 1 x 1 - 1 x 1
2^52 2^53 2^54
= 0.00000000000000000555112
となる。
さらに、実際の 0.3 の数値とコンピュータの 0.1 + 0.2 の差については、
上記から [4] の 0.3 の二進数の 2 の -55 乗の桁以下の数値も合わせて、
1 x 1 - 1 x 1 - 1 x 1 - 1 x 1 - 1 x 1
2^52 2^53 2^54 2^57 2^58
= 0.00000000000000000451028
となる。