9.29.2013

Representation of Floating-Point Numbers

浮動小数点数のまとめ

概要

  • 限られたビットの中で小数を表現する方法の一つが浮動小数点数
  • 今日の実装は処理系、言語を問わずIEEE方式(IEEE 754)が標準
  • とりあえずIEEE方式の倍精度浮動小数点数(C言語のdouble)の仕組みを覚えておけばいい
 
Wikipedia

浮動小数点数 - Wikipedia
IEEE 754 - Wikipedia

IEEE 754

IEEE 754: Standard for Binary Floating-Point Arithmetic

 

ビットの表現

小数を「(符号) 基数2の指数×仮数」で表現するのが基本的な考え方。
倍精度浮動小数点数の場合、64ビットを以下の3つの部分に分けて意味を持たせる。

 

Sign (符号部, 1bit)
  • 0 なら +, 1 なら - を表す
Exponent (指数部, 11bits)
  • 11ビットの符号無し整数で表現できるのは 0〜2047(=2^11-1)。
  • 0(全てのビットが0)と2047(全てのビットが1)は特殊な用途(後述)で使用される。
  • 1〜2046の範囲を、1023 のバイアス付き整数(ゲタ履き表現)で表す。
    例えば符号無し整数の値が 1 であれば -1022、1023 であれば 0、2046 であれば 1023 を意味する。
  • だいたい ±1000 と覚えておけば、ビット数を忘れても思い出しやすい
  • 基数を 10 で考えると、だいたい 1e-308 〜 1e+308 の範囲を表せる
Significand (仮数部, 52bits)
  • 指数部を掛け合わせる前の絶対値
  • 整数部分が 1 になるように指数部を調整する(正規化)ので、整数部分の1は明らかであり表現しない。(hidden bitと呼ばれる)
  • 例えば仮数が10進表記で 1.75 である場合は、2進表記だと 1.11。
    整数部分を除外して、仮数部の表現は 11000000...(以下0が続く) となる。
  • 0付近のごく小さい数を表すために、非正規化表現も用意されている。
    (アンダーフローギャップを埋めるための重要な仕組み)
 

表現の種類

IEEE 754 では5種類の表現が定義されている。

s = sign (0 or 1)
q = exponent (指数部の符号無し整数表記)
c = significand (仮数部の符号無し整数表記) <=小数ではなく整数として見た場合の値

としたときの計算式と合わせて書くと以下のようになる。

種類exponent(q)significand(c)表している値
ゼロ 0 0 +0, -0 (符号の区別がある)
非正規化数 0 1〜 NewImage
正規化数 1〜2046 0〜 NewImage
無限大 2047 0 NewImage
NaN(非数) 2047 1〜 基本的に符号の区別はない (詳細はWikipedia参照)

 

実装の確認

C言語でも可能だが、手っ取り早く Python で確認してみた。
(PyPIからbitarrayをインストールする) 

出力例
                   sign
      double      : v <exponent > <                   significant                    >
======================================================================================
               0.0: 0 00000000000 0000000000000000000000000000000000000000000000000000
              -0.0: 1 00000000000 0000000000000000000000000000000000000000000000000000
               2.0: 0 10000000000 0000000000000000000000000000000000000000000000000000
               3.0: 0 10000000000 1000000000000000000000000000000000000000000000000000
               1.0: 0 01111111111 0000000000000000000000000000000000000000000000000000
               0.1: 0 01111111011 1001100110011001100110011001100110011001100110011010
               nan: 0 11111111111 1000000000000000000000000000000000000000000000000000
               inf: 0 11111111111 0000000000000000000000000000000000000000000000000000
              -inf: 1 11111111111 0000000000000000000000000000000000000000000000000000
2.22507385851e-308: 0 00000000001 0000000000000000000000000000000000000000000000000001
1.79769313486e+308: 0 11111111110 1111111111111111111111111111111111111111111111111111
2.22507385851e-308: 0 00000000000 1111111111111111111111111111111111111111111111111111
4.94065645841e-324: 0 00000000000 0000000000000000000000000000000000000000000000000001

0 件のコメント:

コメントを投稿