WGC1 第4章 浮動小数点表現 4.2 IEEE浮動小数点形式

4.2 IEEE浮動小数点形式

  • 単精度、倍精度、拡張精度
  • Intelが設計した規格

4.2.1 単精度浮動小数点形式

  • C言語のfloat
  • 8ビットの指数
  • 24ビットの仮数(暗黙のHOビット1を含む)
  • 仮数は通常1.0から2.0未満の値を表す
  • 仮数のHOビットは常に1とみなされ、2進小数点のすぐ左の値を表す
  • 仮数の残りの23ビットは2進少数点の右側に位置する
  1.mmmmmmm mmmmmmmm mmmmmmmm

  31              23              15               7             0
  ■日日日日日日日□□□□□□□□□□□□□□□□□□□□□□□□
  ↑ 指数ビット    1              仮数ビット
  符号ビット      24番目の仮数ビットは暗黙ビットで常に1になる

1.0から2.0未満の範囲外の値を表すために浮動少数点の指数部が作用する
浮動少数点形式では、指数に指定された数で2を累乗し、仮数にこの値を掛ける。
指数は8ビットで、イクセス127形式(バイアス127指数)を使う。

4.2.2 倍精度浮動小数点形式

  • 11ビットのイクセス1023指数
  • 53ビットの仮数(暗黙のHOビット1を含む)
  • 1ビットの符号ビット
  • 動作範囲10^±308
  • 精度14と2分の1
  63                  53                                     7             0
  ■日日日日日・・・日日□□□□□□□□□・・・□□□□□□□□□□□□□□□
  ↑ 指数ビット          1              仮数ビット
  符号ビット            53番目の仮数ビットは暗黙ビットで常に1になる

4.2.3拡張精度浮動小数点形式

  • 15ビットのイクセス16383指数
  • 64ビットの仮数
  • 1ビットの符号ビット
  79                  64                                     7             0
  ■日日日日日・・・日日□□□□□□□□□・・・□□□□□□□□□□□□□□□
  ↑ 指数ビット                        仮数ビット
  符号ビット            

80x86のFPUでは、すべての計算が拡張精度形式を使って行われる。
単精度また倍精度の値を読み込むとFPUによって自動的に拡張精度の値に変換される。
同様に単精度また倍精度の値をメモリに格納するときは、FPUによって値が
適切なサイズに丸められてから格納される。
Intelは多数のガードビットによって計算の正確性が確保されることを保証している。
また、すべての計算を80ビットを使って行うことで、Intelは計算で32ビットまたは
64ビットの精度が得られるように努めている。(ただし保証はしていない)
80ビットの計算では、FPUは多数のガードビットがないので、拡張精度計算のLOビットに
ある程度の誤差が紛れ込むことは避けられない。しかし、計算が64ビットまで正しければ、
80ビットの計算では、普通は最低でも64ビットの精度が得られることができる。
ほとんどの場合、精度はより高くなる。正確な80ビットの計算結果が得られるとは
考えられないものの、通常は拡張精度形式を使うと64ビットよりも正確な結果を得られる。
浮動少数点演算をサポートするIntel以外のCPUでは、一般に32ビットと64ビット形式しか
使用できない。このため、これらのCPUで計算を行うと、80x86で80ビット計算を使ったとき
よりも精度の低い結果が返されることがある。

コメント

以前はまったことがある、関数の出力結果がSolarisLinuxで異なった原因はこれだな。
Intel CPUだと80ビットで計算されから、こっちの方が精度がいいということなのか。
Solaris Sparc 64bitの方が精度が悪いからなのか同じ値が求められないということか。
(あってるよね?)

そのときは、プラットフォームごとに異なる結果がでるのは問題なので、
精度の低い方に合わせたが。
このときにコンパイルの最適化オプションによっても結果が変わってて
なんで?なんで?と悩んでてた。
でも、ようやく、結果が違う理由が理解できてよかった。












Randall Hyde、鵜飼 文敏、まつもと ゆきひろ、後藤 正徳、トップスタジオ