コンピュータは浮動小数点数を扱う

 10進数の「10.625」を2進数に変換すると「1010.101」です。では「0.1」は? これは「0.000110011001100……」とまだまだ先が続くのですが、とりあえず小数点以下第10桁で区切ると「0.0001100110」です。もっとも、これは紙の上での話です。コンピュータの世界では「.」が使えません。その代わりに「指数」を使ってこれらの値を表現することにしました。それが「浮動小数点数」です。

浮動小数点数
[画像のクリックで拡大表示]

 「符号部」は符号ビットと同じです。正の数のときは0、負の数のときは1です。残りの「指数部」と「仮数部(かすうぶ)」に入る値は、小数点の位置で決まります。

 まず、2進数の整数部が「1」になるように小数点の位置を移動してください。例えば、「1010.101」であれば左に3つ移動して「1.010101」です。ここに移動した桁数分の重みを掛けて「1.010101×23」にすれば、元の値に戻りますね。同じように「0.0001100110」も指数を使って表現してみましょう。今度は小数点を右に4つ動かすので「1.100110×2-4」です。指数の符号がマイナスになる理由はわかりますか? 小数点を右に動かすごとに値は2倍、4倍……になるので、元に戻すには2分の1倍、4分の1倍……する必要があるからです。

小数点を左右に動かすと……
[画像のクリックで拡大表示]

 さて、この方法を利用すると、どんな値でも「1.〇〇〇〇…×2n」で表現できることにお気付きでしょうか?「 1.〇〇〇〇…×2n」になるように小数点を左や右に動かすから「浮動小数点数」です。このときの小数部が仮数部に、指数部には「n」が入ります。

避けられない実数誤差

 浮動小数点数がどういう値か、何となくイメージできたでしょうか。ほとんどのプログラミング言語には、実数を扱うデータ型として単精度浮動小数点数と倍精度浮動小数点数の2種類が用意されています。Pythonのfloat型は、倍精度浮動小数点数と同じ精度です。

浮動小数点数を扱うデータ型
[画像のクリックで拡大表示]

 率直に言うと、浮動小数点数の中がどうなっているかを知らなくてもプログラムは作れます。ただ、

  • 実数はコンピュータの内部で浮動小数点数という形式で扱われる
  • このときに、ほんのわずかだけれども誤差が生じる

ということだけは覚えておいてください。

 例えば、10進数の「0.1」を2進数に変換すると「0.000110011001100……」のようにいつまでも延々と続く値になります。「0.2」も「0.3」も同様です。小数点以下の桁数をいくら増やしても、きちんとした2進数には置き換えられません。しかし、入れ物の大きさには限りがあります。そこに入るように桁を区切ると、ほんのわずかですが誤差が生じることになります。

 どんなに高性能なコンピュータでも、この誤差をなくすことはできません。大事なことは、私たちが誤差があると理解した上でコンピュータと付き合うことです。

■変更履歴
公開当初、「浮動小数点数を扱うデータ型」の表見出しの「仮数部」と「指数部」が逆になっていました。おわびして訂正します。本文は修正済みです。 [2019/06/26 21:15]
 
公開当初、リスト1の18行目のコメントを「#余りを入れるリスト」としていましたが、正しくは「#整数部を入れるリスト」です。おわびして訂正します。当該箇所は修正済みです。 [2019/07/22 17:15]
出典:「文系プログラマーのためのPythonで学び直す高校数学」(日経BP)
記事は執筆時の情報に基づいており、現在では異なる場合があります。