Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

浮動小数点数の表現方法 (1) (IEEE754 の場合)

講習のスタンダードコースの方で浮動小数点数についての説明があったらしいのですが、それが良く分からないということで質問を受けました。自分もよく分かっていないので、復習をします。
まずは、 IEEE754 規格の場合について考えます。インターネット上に資料がたくさんあるので…… *1

まず前提として、「符合部」「指数部」「仮数部」というものが *ある* ということは分かっているものとします。
最初に浮動小数点数を理解しようとする際の疑問を一通り挙げておこうと思うのですが、その前に「正規化」について書いておきます。

正規化とは
仮数部の有効桁数が最大になるように指数部の値を設定することです。 0.01231.23 x 10^{-2} だと、仮数部に書く数字は後者の方が少なくて済みますよね? そういうことです。昔の x86 アセンブラで言えば、オフセットが 0 に近づくようにセグメントの値を設定するようなもんです。なお、二進数なので、正規化は「仮数部の最上位ビットが 1 になるように指数部を設定する」ことだとも言えます。

さて、浮動小数点数を理解しようとする際の疑問としては、次のようなものがあります。

  1. 数が仮数と指数の 2 つある。でも符合部は 1 つだけ。符合部が表現するのはどちらの符合なのか?
  2. 「符合部が 1 である」というのは、 2 の補数表現を使った結果 1 になったのか、それとも補数表現とは独立に 0/1 の値を取るのか?
  3. 1 \div \infty = 0, -1 \div \infty = -0 を表現する必要があるため、(少なくとも仮数部には) 2 の補数による表現が使えない。
  4. 指数部の単位(10^x として表現するのか、 2^x として表現するのか……)
  5. 指数部を 2^x として表現する場合、仮数部を正規化すると、その最上位桁は必ず "1" となる。この 1 を最初から存在するものと仮定して数の表現を決定すると有効桁数を 1 つ稼ぐことができるが、どうするか?
  6. 指数部の値が 0 のとき、小数点の位置は仮数部から見てどこになるのか(MSB の上、 MSB の下、 LSB の下)?

さて、これらの疑問についてそれぞれ調べていきます。

  • まず、 3. について、 IEEE754 には +0 と -0 という二つのゼロが「存在します」。この条件を満たすため、 1 と 2 はそれぞれ「仮数部の符合である」「補数表現とは独立に 1 になる」ということになります。
  • 4. について、指数部には 2^x の方の表現を使います。
  • 5. について、正規化が行われている場合は「仮数部の最上位桁の上に 1 がある」とした表現を用います。この最上位桁の上にある仮想的なビットのことを「隠れビット」とか言うようです。
  • 6. について、正規化が行われている場合(隠れビットが存在する場合)は、仮数部の最上位ビットと隠れビットの間に小数点があることになります。

さらに、浮動小数点数について調べていくと、指数部の表現方法として「指数部の値に 127 を足す」とか何とか書かれていることに気付きます。これは、指数部が負数の際に 2 の補数表現を用いるのではなく、「指数部の値に 127 を足した値を実際の指数とする」ことで負数を含む数の範囲をカバーした表現を実現する、というものです。なぜこんな表現方法を使っているのかは分かりませんが……。

このエントリに書いた浮動小数点数の表現方法の具体例としては、 http://www.nextindex.net/java/binary.html の "浮動小数点数" のセクション、 http://www.math.meiji.ac.jp/~mk/labo/text/ieee_format.pdf の "3 先頭のビットが符号を表わすこと" 以降が分かりやすいです。

さて、講習のスタンダードコースの方で説明があった浮動小数点数はこれとは異なる表現をしているようでした。それについては別のエントリで。