2進数「float型」での浮動小数点の表現は、次のようになります。
※これまで小数というと「double型」を使ってきましたが、「double型」は64ビットもあるため説明しにくいので、「float型」(32ビット)で説明します。
「符号」(「仮数」+1) × 2 の 「指数−127」乗
例えば、
「符号」が「+」 「仮数」が「2進数(0.1)」 「指数」が「128」
の場合
+(0.1+1) × 2 の (128−127)乗
となり、
+1.1 × 2 の 1乗
2進数「1.1」を10進数に直すと、「1.5」になるため、
+1.5 × 2 = +3
となります。
逆に、10進数「+3」を2進数の浮動小数点に変形させる場合、
10進数「3」を2進数で表現すると「11」
表現形式を浮動小数点形式に変えてみると、
+11.0 × 2 の 0乗
「0乗」の部分は「127を引いた結果」で無ければならないため、
+11.0 × 2 の (127−127)乗
となります。
さらに変形して、
+1.1 × 2 の (128−127)乗 ← つまり「1乗」
「仮数」を(0.?+1)に直し、
+(0.1+1) × 2 の (128−127)乗
これで完成です。
情報として保存するのは、
「符号」の「+」 「仮数」の「1」 (10進数と同じく0.は省略) 「指数」の「128」
で良いのです。
実際には、この情報を2進数で扱っています。
「符号」だけは数値ではないので、「+」であれば「0」、「−」であれば「1」としています。
C言語で小数を扱える変数の型は「float」と「double」ですが、ここでは「float」を使って説明しています。
「float」型は「32ビット(2進数32桁)」の大きさです。
この32ビットを次のように分けて使います。
「符号」 → 1ビット 「指数」 → 8ビット 「仮数」 → 23ビット
上の10進数「+3」を「float」型に当てはめてみると、
「符号」 → 0 「指数」 → 128(10進) → 10000000 「仮数」 → (0.)10000000000000000000000
全部並べると、
0 10000000 10000000000000000000000
分かりやすく4桁ずつ区切ると
0100 0000 0100 0000 0000 0000 0000 0000
となり、
16進数で、
40400000
となります。
実際にどのように表示されるか試してみます。
※このプログラムで使っている命令や考え方はこのコラムを書いている時点では説明しておりません。
もっとずっと後になって説明する内容ですので、今のところは実行するだけにしてください。
<sample program col019-01>
#include <stdio.h> union Sample { float float_data; unsigned char char_data[4]; }; int main(void) { union Sample data; int i; data.float_data = 3.0f; for (i = 3; i >= 0; i--) { printf("%02x ", data.char_data[i]); } printf ( "\n"); } |
<実行結果>
40 40 00 00 続行するには何かキーを押してください・・・
「3.0f」と書いてある部分を色々変更してみてください。
試してみたら「誤差について」を読んでみてください。
ブラウザの戻るボタンで戻ってください。