倍精度浮動小数点数

64ビットの浮動小数点数形式
倍精度から転送)

(ばいせいどふどうしょうすうてんすう、: double-precision floating-point number)は、64ビットの浮動小数点数表現である。

倍精度とは単精度に対する表現であり、これは32ビットを1ワードとする32ビットアーキテクチャをもとにしている。

[いつ?]FORTRANでは、単精度(REAL型)よりも精度が高ければ倍精度(DOUBLE PRECISION型)を名乗ることができた(そもそもワードの長さも浮動小数点のフォーマットも機種ごとにまちまちだった)。IBMのSystem/360で採用され大型機の事実上の標準となった、指数の基数が16の浮動小数点形式は、32ビット単精度では最悪の場合の精度が十進で6桁程度となり、技術計算では倍精度以上を使わねばならないという問題があった。(注:FORTRANではREAL型が1ワード、DOUBLE PRECISION型が2ワードという前提だった)

浮動小数点算術に関する標準であるIEEE 754では、単精度は32ビット(4オクテット)、倍精度は64ビット(8オクテット)である。いずれにしろ、「倍」というのは、精度に関係する仮数部(後述)の長さが正確に2倍である、といったような意味ではなく、全体の長さが2倍である所から来ているので、実際の所「倍精度」というのはかなり大雑把な言い方に過ぎない。

倍精度浮動小数点数の形式

編集

倍精度浮動小数点数は単精度浮動小数点数に比べて性能や帯域幅のコストがかかるが、表現できる数値の範囲が広いためPCでもよく使われている。浮動小数点方式一般に言えることであるが(単精度の場合と同様)指数部に使われる部分があるために、同じサイズの固定長整数が表現可能な値のうち、ある範囲より絶対値が大きいものについては、その全てを正確に表現することはできない。IEEE 754:2008でbinary64として標準化されたパラメータは次の通りである。

  • 符号ビット ( ): 1 ビット
  • 指数部 ( ): 11 ビット
  • 仮数部 ( ): 52 ビット

指数部が全て 0(ゼロ、および非正規化数)の場合を除き、仮数部で表現されるビットパターンのさらにひとつ上の桁に暗黙の 1 のビットがあるとみなす表現法(いわゆる「ケチ表現」)により、通常の数(正規化された数)の精度は、53ビット相当(十進に直すと約16桁、 )である。ビットのレイアウトは以下のようになる(具体的なレイアウトは、一般的なバイトアドレッシングのコンピュータにおいて、エンディアンの違いなどによる影響を受けることがあるが、それについては必ずしも標準化されていない)。

 

64ビットの「倍精度」データで表される実際の数値は、符号を  、バイアスのある指数部を  、52ビットの仮数部のビット列を とすると、  となり、より正確に表すと次のようになる。

  •  

252=4503599627370496 と 253=9007199254740992 の間で表現できる数値は正確に整数に対応している。253 から 254 までの範囲では、常にその2倍となるので、偶数しか表現できない。逆に 251 と 252 の間の範囲では間隔が0.5になる。

数値の小数部の間隔は 2n から 2n+1 の範囲で 2−52 から 2−53 までである。従って最も近い値への数値の丸め誤差の最大(計算機イプシロン)は 2−53 となる。

指数部の符号化方式

編集
  • Emin (00116進) = −1022
  • E (50) = −973
  • Emax (7FE16進) = 1023
  • 指数部バイアス (3FF16進) = 1023

指数部バイアスは、エクセスNとも言う。詳しくは符号付数値表現を参照されたい。真の指数値は、指数部の値から指数部バイアスを引いた値となる。

00016進 と 7FF16進 は予約された指数値である。

  • 00016進 は 0(仮数部も0)と非正規化数(仮数部が0でない)を表現するのに使われる。
  • 7FF16進無限大(仮数部が0)やNaN(仮数部が0でない)を表現するのに使われる。

従って、全てのビットパターンが符号として意味がある。これらの例外を除くと、倍精度浮動小数点数は次のように表される。

 

倍精度浮動小数点数の例

編集
バイト列(16進法表記) バイト列が表現している値
3FF0 0000 0000 0000  
3FF0 0000 0000 0001  (1より大きい最小の数)
3FF0 0000 0000 0002  
4000 0000 0000 0000  
C000 0000 0000 0000  
0000 0000 0000 0001  (正の最小の非正規化数)
0010 0000 0000 0000  (正の最小の正規化数)
7FEF FFFF FFFF FFFF  (倍精度浮動小数点数の最大値)
0000 0000 0000 0000  
8000 0000 0000 0000  
7FF0 0000 0000 0000  
FFF0 0000 0000 0000  
3FD5 5555 5555 5555    は単精度とは異なり、切り下げられる。これは仮数部のビット数が奇数であるため。)

より詳細な例として 3FD5 5555 5555 555516進 の場合は以下の通りに考える。

項目
符号 016進
指数部 3FD16進(=102110進
指数部バイアス 102310進 (上述)
仮数部 5 5555 5555 555516進
2(指数部 − 指数部バイアス) × 1.仮数部 ※仮数部はこの段階では十進に変換されない
= 2−2 × (15 5555 5555 555516進 × 2−52)
= 2−54 × 15 5555 5555 555516進
= 0.333333333333333314829616256247390992939472198486328125
≈ 1/3

MSXの場合

編集

MSX-BASICの演算ルーチンMATHPACKの場合、同様に8バイトで表すが、IEEE 754とは異なり

  • s(符号ビット): 1
  • y(指数部の幅): 7
  • x(仮数部の幅): 56
 syyy yyyy xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

であり、指数部をバイナリ、仮数部をBCDで表現する。 そのため、有効数字は正確に10進で14桁で、指数は±63乗である。 他のパソコンのBASICはほとんどが2進での演算であった(他にBCDを採用した機種としてFP-1000がある)。

2進小数の主な利点は高速性とメモリ消費にあり、BCD小数の主な利点は現実の10進小数を誤差なく扱える事にあったと言ってよい。 2進小数は原理上0.5や0.25、0.375といったn/(2^m)以外の値、つまり0.1や0.2といった数値を正確に扱う事が苦手であり(表示上は補正されているが、10進小数を2進小数に変換すると殆どの場合循環小数となり、微小な切り捨てが発生する)高速性よりも(10進の世界での)正確性が優先されるようなケースにおいてBCD小数は強みを発揮した(各種利息計算など)。

ただし当時のスペックにおいて10進小数は相応に重い処理であり、DAAという10進補正用の専用CPU命令を持っていたZ80であっても複雑な演算になればなるほど(例えば三角関数や対数関数のような数学関数)2進小数より負荷が増していく。 MSX-BASICにおいて10進小数が採用された理由は、マイクロソフトBASICの中でも比較的後期に開発され新しい実装を試せた事、加えてホームコンピュータという需要の開拓においてより一般性を高めたいアスキー側の狙いがあったと考えられる。

CPUの浮動小数点ユニットとの相互運用を視野に入れなければならない現代の言語では、特殊な用途を除いてBCD小数を目にする機会は少ない。

関連項目

編集
  • IEEE 754
  • 浮動小数点数