パスワードを忘れた? アカウント作成
473236 journal

novaの日記: IEEE 754-1985 ふぉーまっと 1

日記 by nova

IEEE 754-1985 フォーマットの倍精度浮動小数点数を、10進数の実数に復元するメモ

 プログラムなら、対象の 8byte を double 型に突っ込めば完了。手動でシコシコやろうとすると結構手間が掛かります。

 以下の hex が与えられたとします。

40 8f 40 00 00 00 00 02

コレは、1000.0000 を IEEE 754-1985 フォーマット (倍精度浮動小数点数 [64bit]) に変換したモノです。 コレを 1000.0000 に復元してみます。

 まず、バイナリにします。

01000000 10001111 01000000 00000000 00000000 00000000 00000000 00000010

 続いて、符号部・指数部・仮数部 に分けます。倍精度浮動小数点数 [64bit] の場合は、 上位ビットから、符号部 [1bit]、指数部 [11bit]、仮数部 [52bit] と決まっているので、

  • 符号部: 0
  • 指数部: 10000001000
  • 仮数部: 1111010000000000000000000000000000000000000000000010

となります。符号部が 0 なら正の数、1 なら負の数です。このデータの符号部は 0 なので、正の数です。

 指数部は 10000001000 なので、コレを 10進数に直すと 1032。 しかし、倍精度浮動小数点数 [64bit] の指数部は +1023 でバイアスされています。 よーするに、実際の指数に 1023 が足してあります。コレは、常に正の数にして格納する為です。 ゆえに、指数は 1032 - 1023 で 9 となります。

 仮数部には暗黙の了解として、上位に 1 が付きます。コレは、仮数部の基になる数は 1 以上 2 未満であるコトが約束されている為です。 IEEE 754-1985 フォーマット にした時点で、整数部分は 1 になっているハズなので、仮数部には少数部分しか格納されていません。 つまり、本来の姿は、

1.1111010000000000000000000000000000000000000000000010

となります。そして、2 の指数階乗を掛けます。式にすると

1.1111010000000000000000000000000000000000000000000010 × 29

です。計算すると

1111101000.0000000000000000000000000000000000000000010

ですので、10進数に直すと 1000.0000... となります。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • printf() で打ち出してしまうと味も素っ気もありませんが、

    int dtoi( double f )
    {
            return (int)(f);
    }

    として、コンパイルして見ると面白い結果が得られる場合があります。
    # コンパイラ依存ですが。あ、int -> double の方が余計なコードが無くて
    # 判り易いかも。

    なんじゃそのマジックナンバーは??!? と目を白黒することしばし…しばらく検算して「おぉっ」と思わず膝を打ちます。

    私は RS/6000 用 xlc でこれを見て、3時間ほど本業を忘れてしまいました。
    --
    fjの教祖様
typodupeerror

計算機科学者とは、壊れていないものを修理する人々のことである

読み込み中...