【概要】
浮動小数点数は、実数の数値を扱うと必ず必要になる数値表現ですが、
PICでこの浮動小数を扱うには、PICのハードウェアは直接扱えるようには
なっていませんから、ソフトウェアでこれを実現する必要があります。
ソフトウェアで浮動小数点数を扱うときには、浮動小数点数を何らかの
メモリのデータとして扱う必要があるわけですが、このときの表現方法が
複雑になりますので、これを統一した表現で扱うように標準規格が定められて
います。これが「IEEE754」という標準規格です。正式名称は下記です。
”ANSI/IEEE std 754-1985
IEEE Standard for Binary Floating-Point Arithmetic”
【浮動小数点数の表現】
IEEE754に則した単精度の浮動小数点数の表現は下図のようになります。
この図のように浮動小数点数を
(符号)(仮数部) × 2の(指数部)乗
というように表現して表します。
《正規化(Normalize)》
浮動小数点数は、非常に大きな数値から小さな数値まで扱いますので、
有効数値をいつも同じになるようにしておく必要があります。そうしないと
大きな数値と小さな数値では精度に差が出てしまうからです。
例えば 10進数で 0.0000026 と 123.0065 を扱う場合には、そのままでは
同じ精度での扱いは無理です。
そこで下記のように、小数点の位置がいつも同じようになるようにしてしまえば
有効数値を同じ桁数にすることができます。
2.600000 × 10の-6乗
1.230065 × 10の2乗
これと同じことを2進数でも行います。そして2進数の場合には、IEEE754では、
最上位ビットが常に1になるように正規化します。
つまり、1.0000・・・・から1.1111・・・の間になるように小数点の位置をずらします。
そうすると最上位ビットは常に「1」ということになります。
Microchipでは、このことを利用してMicrochipでの浮動小数点数の表現は下図の
ようになっています。つまり常に1と決まっている最上位ビットは記述しないことに
してしまって、その代わりこれを符号ビットとして使うことにしてしまいました。
これを4バイトのデータとして下図のようにメモリに格納しています。
さらに指数部は±の表現ができるように、0x7Fだけ加算した値としています。
《特別な値》
特別な値としては、0 と ±1があります
「0」 は 0x00 00 00 00 となります。
「1」 は 0x7F 00 00 00
「-1」は 0x7F 80 00 00 となります。
【10進数実数から2進浮動小数への変換】
実際の10進数の整数を上記の4バイトの2進浮動小数に書き換えてみましょう。
手順は次のようにします。
・10進整数を2進整数に変換する。(Windowsの「電卓」でできます。)
・最下位の右に小数点があるものとして、それを最上位の1まで小数点を
ずらして 《1.xxxx × 2の乗数》 の形に変換して正規化する。
小数点をずらした数が乗数となる。
・乗数に0x7Fを加算して指数部を求めます。
・1.xxxxの最上位の1を無視してxxxxの部分から仮数部を求めます。
(例1) 10進数の10
10を2進数に変換 → 1010 (0xA)
これを正規化する → 1.01×2の3乗
指数部 → 0x7F + 3 = 0x82
仮数部 → 1010 0000 0000 0000 0000 0000
最上位を0にして → 0010 0000 0000 0000 0000 0000
(マイナスの時は最上位は1になる)
結果 → 0x82 20 00 00
(例2) 10進数の100
100を2進数に変換 → 0110 0100 (0x64)
これを正規化する → 1.1001 × 2の6乗
指数部 → 0x7F + 6 = 0x85
仮数部 → 1100 1000 0000 0000 0000 0000
最上位を0にして 0100 1000 0000 0000 0000 0000
結果 → 0x85 48 00 00
(例3) 10進数の1000
1000を2進数に変換 → 0011 1110 1000 (0x3E8)
これを正規化する → 1.111101× 2の9乗
指数部 → 0x7F+9=0x88
仮数部 → 0111 1010 0000 0000 0000 0000
結果 → 0x88 7A 00 00
次に10進数の実数を2進数の浮動小数に変換してみましょう。
実数の整数部は上記と同じやり方ですので、問題なくできると思いますが、
小数部はちょっと面倒ですが、下記の値を順に引き算しながら2進数に変換
します。
2の−1乗 = 0.5
2の−2乗 = 0.25
2の−3乗 = 0.125
2の−4乗 = 0.0625
2の−5乗 = 0.03125
2の−6乗 = 0.015625
2の−7乗 = 0.0078125
(例4) 10進数の123.15625
123を2進数に変換 → 0111 1011 (0x7B)
これを正規化する → 1.111011 × 2の6乗
指数部 → 0x7F+6=0x85
仮数部(整数分) → 0111 011x xxxx xxxx xxxx xxxx xxxx xxxx
(xの部分が小数部の仮数部)
小数部分の仮数部は下記手順で求めます。
0.5と0.25は引けない → 0111 0110 0xxx xxxx xxxx xxxx
0.15625 − 0.125 = 0.03125 → 0111 0110 01xx xxxx xxxx xxxx
0.0625は引けない → 0111 0110 010x xxxx xxxx xxxx
0.03125 − 0.03125 = 0 → 0111 0110 0101 0000 0000 0000
結果の浮動小数 → 0x85 76 50 00
(例5) 10進数の1.54
1を2進数に変換 → 1
これを正規化する → 1.0 × 2の0乗
指数部 → 0x7F+0=0x7F
整数部の仮数部 → 0xxx xxxx xxxx xxxx xxxx xxxx
小数部の変換
0.54 − 0.5 = 0.04 → 01xx xxxx xxxx xxxx xxxx xxxx
0.25 0.125 0.0625は引けない → 0100 0xxx xxxx xxxx xxxx xxxx
0.04 − 0.03125 =0.00875 → 0100 01xx xxxx xxxx xxxx xxxx
0.015625は引けない → 0100 010x xxxx xxxx xxxx xxxx
0.00875−0.0078125 → 0100 0101 xxxx xxxx xxxx xxxx
−−−−−
最終仮数部 → 0100 0101 0001 1110 1011 1000
結果の浮動小数 → 0x7F 45 1E B8
(例6)10進数の0.0695
1より小さい小数の場合には正規化して1.xxx × 2の−n乗という値にする。
小数部の正規化 2のn乗を掛ける→ 0.0695×16=1.112
従って正規化すると→ 1.112×2の−4乗
指数部 → 0x7F−4=0x7B
1.112の整数部の仮数部 → 0xxx xxxx xxxx xxxx xxxx xxxx
小数部0.112の仮数部への変換
0.5、0.25、0.125は引けない → 0000 xxxx xxxx xxxx xxxx xxxx
0.112−0.0625=0.0495 → 0000 1xxx xxxx xxxx xxxx xxxx
0.0495−0.03125=0.01825 → 0000 11xx xxxx xxxx xxxx xxxx
0.01825−0.015625=0.002625 → 0000 111x xxxx xxxx xxxx xxxx
0.0078125は引けない → 0000 1110 xxxx xxxx xxxx xxxx
−−−−−−
最終仮数部 → 0000 1110 0101 0110 0000 0100
結果の浮動小数 → 0x7B 0E 56 04