浮動小数点数の表現方法


【概要】

浮動小数点数は、実数の数値を扱うと必ず必要になる数値表現ですが、
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 011
0 0xxx xxxx xxxx xxxx
   0.15625 − 0.125  = 0.03125  → 0111 0110 0
1xx xxxx xxxx xxxx
   0.0625は引けない         → 0111 0110 01
0x xxxx xxxx xxxx
   0.03125 − 0.03125 = 0     → 0111 0110 010
1 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    → 0
1xx xxxx xxxx xxxx xxxx xxxx
   0.25 0.125 0.0625は引けない → 01
00 0xxx xxxx xxxx xxxx xxxx
   0.04 − 0.03125 =0.00875   → 0100 0
1xx xxxx xxxx xxxx xxxx
   0.015625は引けない       → 0100 01
0x xxxx xxxx xxxx xxxx
   0.00875−0.0078125       → 0100 010
1 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は引けない  → 0
000 xxxx xxxx xxxx xxxx xxxx
   0.112−0.0625=0.0495     → 0000
1xxx xxxx xxxx xxxx xxxx
   0.0495−0.03125=0.01825    → 0000 1
1xx xxxx xxxx xxxx xxxx
   0.01825−0.015625=0.002625  → 0000 11
1x xxxx xxxx xxxx xxxx
   0.0078125は引けない      → 0000 111
0 xxxx xxxx xxxx xxxx
   −−−−−−
   最終仮数部          → 0000 1110 0101 0110 0000 0100
  結果の浮動小数         → 0x7B 0E 56 04




  目次ページに戻る