【プログラムはなぜ動くのか】第3回コンピュータが小数点計算を間違う理由

あなた

プログラムってどうして動くの?

プログラムが動く理由について解説しているこのシリーズで今回が第3回になります。前回2進数について解説しました。今回は2進数の小数点計算について説明したいと思います。

改めてになりますが、コンピュータ内部ではすべて2進数で制御が行われています。つまり2進数の計算をマスターすることによって、コンピュータのプログラムの仕組みついて理解することができます。

プログラムが動くまでの全体の流れ

今回は全体の流れの中で、③の部分を解説していきます。内容はコンピュータにおける2進数の小数点計算についてです。

コンピュータが小数点計算を間違える?

正確無比なコンピュータが計算を間違えるはずがないと思っている人も多いと思います。しかし、実際にはプログラムの実行結果として、正しい値が得られないことがあります。そのひとつの例がコンピュータで行う小数点計算です。

けしてプログラムが間違っているわけでも、コンピュータが間違っているわけでもありません。2進数での小数点以下の数字の知識があれば、コンピュータが計算を間違う理由は至極当然のものだと分かります。そして、計算間違いの原因がわかれば、計算間違いを回避する方法もわかります。

0.1を100回加えても10にならない

ではコンピュータが計算を間違えてしまう具体例を示しておきたいと思います。「0.1」を100回足すと答えはなんになるでしょうか。暗算でもわかります、答えは「10」ですよね。しかしコンピュータに計算させたときの実行結果は10にはなりません。

実際に見てもらうのがいいともいますので、0.1を100回加えるプログラムとその実行結果を示しておきます。

このように「0.1」を100回加えても、答えは「10」にはなりません。

「小数点を持つ2進数」を「10進数」であらわすには

そもそもコンピュータはデータをすべて2進数であらわしています。もちろん数字の小数点以下でも2進数で表しています。では具体的に2進数で小数点をもつ数字を考えてみましょう。

「11.0011」という2進数について考えてみます。この2進数を10進数に直してみようと思います。どうすればこの「11.0011」を10進数であらわすことができるでしょうか。

もしわからない場合は、前回の第2回の2進数について見直してみてください。2進数の10進数への変換の方法は、各桁に「重み」をかけてそれぞれを足せば、いいのでしたよね。実際に「11.0011」を10進数に変換にする方法を、下の表にまとめておきます。

 

コンピュータが小数点計算を間違える理由

なぜコンピュータは小数点計算を間違えてしまうのでしょうか。結論から言ってしまうと、10進数の小数点数の中には、2進数に正確に変換できないものがあるからです。小数点以下4桁の2進数であらわせる値について表を、表しておきます。

この表の0.0625の数値の部分を見てください。0.0625の次は一気に0.125になっています。つまり、ここからいくら桁数を増やしても2のマイナス○○乗の数を付け加えても、「0.1」を2進数で作ることができません。

MEMO
ちなみに実際10進数の0.1を2進数に変換すると0.0001100110011…(以下0011)の繰り返しとなります。

もうお分かりいただけたと思いますが、計算プログラムで正しい値が得られなかった理由は、2進数で正確に表せない10進数の値があるため、答えが近似値になってしまうからです。

コンピュータの計算間違いを回避するには

このコンピュータの小数点以下の計算間違いを回避するには2つの方法があります。

(1)間違いの無視

実際は非常に小さな値の違いしかないので、そのまま無視しても問題ないことが多いです。たとえば工業製品などでも、10 cmが10.000002cmであるかは、そこまで重要ではありません。

(2)小数点計算を整数に置き換えて計算する

小数点の計算をすると誤差が起きてしまうことがあるので、そういった場合は、小数を整数に置き換えて計算します。例えば今回の計算の例なら、1を100倍して、その結果を10で割って、値を示せばいいのです。

まとめ

内容は前回の2進数と同じで、2進数の小数点を扱いました。これで2進数に関する計算はほぼほぼマスターしたことになります。お疲れ様でした!

次回はデータを格納するメモリーを説明します。メモリーを意識できるとC言語の配列やポインタの意味を理解できるはずです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください