IEEE 754

出典: フリー百科事典『ウィキペディア(Wikipedia)』

IEEE 754IEEE 浮動小数点数演算標準)とは、浮動小数点数の計算で最も広く採用されている標準規格であり、多くのCPUFPU、またソフトウェアで実装されている。この標準規格は浮動小数点数の表現形式(+0-0非正規化数を含む)を規定するとともに特殊な値(無限大NaN)も規定し、浮動小数点演算でのそれらの値の扱い方を規定している。また、5種類の丸め (端数処理) モードと5種類の例外(例外発生時の状況とその後の動作も含む)も規定している。

多くのコンピュータ言語でも、浮動小数点数処理の一部または全部にIEEE 754が採用されている。IEEE 754が制定される前に成立したC言語などは、仕様上はIEEE 754が必須となっていないものの、IEEE 754を採用したコンピュータ・アーキテクチャの普及に伴い、最近の処理系では、自然とIEEE 754が採用されることが多い。一方で、中にはJavaC#など言語仕様としてIEEE 754を必須としているものもある。

現在の規格は、2008年8月に制定されたIEEE 754-2008である。これには、IEEE 754制定当初の規格であるIEEE 754-1985、ならびに基数非依存の浮動小数点演算の標準規格のIEEE 854-1987の両者がほぼすべて吸収されている。IEEE 754-2008が制定されるまでは、IEEE 754rと呼ばれた。

このIEEE 754-2008は、7年掛けてIEEE 754-1985から置き換えたものである。なお、IEEE 754-1985当初からの二進形式(単精度・倍精度)は、そのままIEEE 754-2008にも含まれている。さらに、IEEE 754-2008では、新たに二進形式1つ、十進形式2つも加わって、計5つの基本形式が存在する。IEEE 754-2008に従う実装では、これらのうち少なくとも1つの基本形式を算術演算と情報交換のために実装しなければならないとされている。

正式な規格名は、IEEE Standard for Floating-Point Arithmetic (ANSI/IEEE Std 754-2008)である。

目次

[編集] 形式

IEEE 754において、浮動小数点数データを取り扱うための符号化が形式 (Formats) として定められている。その中では次のデータを表現できる。

  • 2または10を基数とする有限数。各有限数は、符号s(0または1)、仮数c、指数qの3つの整数で表現し、(−1)s × c × bqという値を意味する。ここで、bは2または10の基数である。例えば、符号が1(負数を意味する)、仮数が12345、指数が−3で、基数が10だった場合、−12.345という値を表す。
  • +∞と−∞。
  • 2種類の非数 (NaN)。NaNにはクワイエットNaNとシグナリングNaNが存在する。どちらのNaNでも、追加情報を伝えられる余裕が設けられている。

正の有限数は基数 (b) と指数 (p) を基に一意に決定される。そのために指数についてのパラメータemaxを導入して次のようにする。

  • cは0からbp−1までの値でなければならない(例えばb = 10 かつ p = 7 ならば c は0から9999999の範囲を取る)。
  • qは1−emaxq+p−1 ≤ emaxでなければならない(同様に、例えばp = 7 かつ emax = 96 ならばqは−101から90の範囲を取る)。

括弧内の例のパラメータを用いた場合、最も小さい0でない値は1×10−101と表現され、最も大きい値は9999999×1090 (または9.999999×1096)と表現される。これらの数は、正規数と呼ばれる。一方、正負の最も0に近い正規数である−1×10−95と1×10−95に挟まれた区間は、非正規数として表現される。

[編集] 基本形式

IEEE 754標準では、5種類の基本形式を定めており、基数や符号化して使用するビット数に応じて名前が付けられている。その内訳は、32/64/128ビットで表現する3種類の二進浮動小数点形式と64/128ビットで表現する2種類の十進浮動小数点形式からなる。このうち、二進形式の初めの2種はIEEE 754-1985で単精度 (single)・倍精度 (double)と呼ばれた形式である。3つ目の二進形式は、四倍精度 (quad) とも呼ばれる。同様に、十進形式の2種も倍精度・四倍精度と呼ばれる。

パラメータ →
形式名
b
基数
p
(ビット・桁)
emax
binary32 2 23+1ビット +127
binary64 2 52+1ビット +1023
binary128 2 112+1ビット +16383
decimal64 10 16桁 +384
decimal128 10 34桁 +6144

[編集] 算術形式

算術その他の演算で使用される形式は、符号化したときのものと一致していなくても構わない(つまり、実装は、内部で異なる表現を使用してもよい)。ただし、そのような内部形式も、有限数の表現できる集合が定められるようパラメータ (b, p, emax) はきちんと定義されている必要がある。

[編集] 交換形式

交換形式は固定長のビット列での浮動小数点数の交換や記録を意図した形式である。

二進浮動小数点数用に、16/32/64ビットならびに32の倍数で128ビット以上の交換形式が定義されている。16ビット形式は、グラフィック用途など小さな値の交換または記憶に用いることが想定されている。

[編集] ここでのビットの示し方について

Wビットの幅を持つワードがある場合、整数でビットに番号を振る。その番号の範囲は 0 − W−1 であり、0番のビットが右端となる。0 番のビットは一般にLSBである。

[編集] 32ビット単精度

単精度二進化浮動小数点数は、32ビットワードに格納される。

  1     8               23              ビット幅
 +-+--------+-----------------------+
 |S|  Exp   |  Fraction             |
 +-+--------+-----------------------+
 31 30    23 22                    0    ビット番号 (0が右)
    バイアス +127

S は符号、Exp は指数部、Fraction は仮数部である。

指数部はバイアスまたはエクセスと呼ばれる表現形式であり、実際の値にある固定値emax = 127を加算している。このような表現にしているのは浮動小数点数同士の比較を単純にするためである。指数部は大きな値も小さな値も表せるように負の値にもなるが、これを2の補数で表すと、全体の符号 S とは別に Exp も符号を持つことになり、単純な大小比較ができなくなってしまうのである。そのため、指数部はバイアスされて常に正の値となるような形式で格納される。単精度数の指数部は −126 − +127 に 127 を加えて、1 − 254 としている(0 と 255 は特殊な意味を持つ。後述)。浮動小数点数を解釈するときは、バイアスを減算して実際の指数を求める。

表現可能なデータは指数部の値によって区別され、仮数部の値にも影響される。指数部も仮数部も符号無しの二進整数であることに注意されたい(指数部は 0 – 255)。

種類 Exp(指数部) Fraction(仮数部)
ゼロ 0 0
非正規化数 0 ゼロ以外
正規化数 1 – 254 任意
無限大 255 0
NaN 255 ゼロ以外の任意

最も一般的な正規化数では、Exp はバイアスされた指数であり、Fraction は仮数の一断片である。さきほどの(−1)s × c × bqと対応づけると次のようになる。

s = S
q = Exp − emax (ここではemax = 127であり、換言すれば、指数に 127 を加算して格納されている。「127でバイアス」しているとも言う)
b = 2
c = 1.Fraction (二進数で、二進数の 1 の後に小数点があり、その後に二進数のビット列の Fraction が続く)したがって、1 ≤ c < 2.

なお、−126 は正規化数の最小指数である。

正規化数以外の場合

  • 非正規化数の場合 q = −126 で、c が 0.Fraction とする。(q は −127 ではない。仮数の小数点以上の部分が0になっている関係で、指数を −126 としてバランスをとっている。)
  • ゼロは二種類存在する。+0(s が 0)と −0(s が 1)である。
  • 無限大も二種類存在する。+∞(s が 0)と −∞(s が 1)である。
  • NaN にも符号や仮数があるが、分析以外の目的では使えない。Fraction の先頭ビットで 「signaling NaN」と「quiet NaN」を区別する。
  • NaN と 無限大 は Exp フィールドが全て 1 である。

[編集]

十進数 −118.625 を IEEE 754 で表現してみよう。

  • まず、符号と指数と仮数に分割する必要がある。
  • 負の数なので、符号は "1" となる。
  • 次に符号無しで2進数で書くと、1110110.101 となる(二進記数法を参照されたい)。
  • 小数点を左に移動させ、1 だけを左に残す。1110110.101=1.110110101×26 となる。これが正規化された浮動小数点数である。
  • Fraction は小数点の右側だけであり、足りないビット数のぶんだけ 0 で埋め 23ビットにする。結果は 11011010100000000000000 である。
  • 指数は 6 であるが、二進数になおしてバイアスをかける必要がある。32ビット IEEE 754 形式では、バイアスは 127 なので 6 + 127 = 133 となる。二進数に変換すると 10000101 である。

この結果をまとめると以下のようになる。

  1     8               23              ビット幅
 +-+--------+-----------------------+
 |S|  Exp   |  Fraction             |
 |1|10000101|11011010100000000000000|
 +-+--------+-----------------------+
 31 30    23 22                    0    ビット位置 (LSBが 0)
    バイアス +127

[編集] 64ビット倍精度

倍精度は各フィールドの幅が広くなっているだけで、考え方は同じである。

  1     11                                52
 +-+-----------+----------------------------------------------------+
 |S|  Exp      |  Fraction                                          |
 +-+-----------+----------------------------------------------------+
 63 62       52 51                                                 0
    バイアス +1023

NaN と無限大は Exp を全て 1 (2047) にして表す

正規化数では、指数は emax = +1023 でバイアスされる(したがって e は Exp − 1023)。非正規化数の指数は −1022 である(−1023ではない理由は単精度と同じ)。単精度と同じく、無限大とゼロには符号がある。

[編集] 浮動小数点数の比較

浮動小数点数の比較は浮動小数点命令を使うのが最良である。しかし、形式やエンディアンや符号が同じであれば、数値をビット列としてバイト単位に比較することも不可能ではない(NaNは除く)。

ふたつの正の数値 a と b について a < b という比較を行う場合、これを符号無しの整数とみなして比較しても同じ結果を得られる。換言すれば、(NaN以外の)ふたつの正の浮動小数点数は符号無し整数として比較できる(ただし、エンディアンが異なる場合は比較できないので、移植性が問題となるコードでC言語の union を使ってこれをするのはお勧めできない)。これは辞書式順序(lexicographic ordering)の例である。

[編集] 十進浮動小数点数

十進浮動小数点数に対しては、32の倍数のビット数での交換形式が定義されている。

二進の場合と同様、符号、指数、仮数と符号化していくが、仮数部は十進の各桁をより詰め込めるよう、Densely Packed Decimalを採用し二進と比べ複雑になっている。いずれにせよ符号・指数・仮数によって表現すること自体に変わりはない。また、NaNの表現は二進同様、正規化数とは別扱いである。

[編集] 浮動小数点数の丸め

IEEE 754-2008標準では5種類の丸めアルゴリズムが定義されている。うち2種類は最近接な値に丸める方法であり、残り3種類は方向丸めと呼ぶ。

[編集] 最近接丸め

最近接丸め(偶数)
最も近くの表現できる値へ丸める。表現可能な2つの値の中間の値であったら、一番低い仮数ビットが0になるほうを採用する。これは二進での標準動作かつ十進でも推奨となっている。
最近接丸め(0から遠いほうへ)
最も近くの表現できる値へ丸める。表現可能な2つの値の中間の値であったら、正の値ならより大きいほう、負の値ならより小さいほうの値を採用する。

[編集] 方向丸め

0方向へのまるめ
0に近い側へ丸める。切り捨て (truncation) とも呼ばれる。
+∞への丸め
正の無限大に近い側へ丸める。
−∞への丸め
負の無限大に近い側へ丸める。

[編集] 演算

実装には、算術形式に対して次の演算が要求される。

  • 算術演算(加減乗除・平方根・積和算・剰余・その他)
  • 変換(複数形式間・文字列との相互・その他)
  • スケールと量子化
  • 符号の複製・操作(絶対値・負符号・その他)
  • 比較・全順序
  • NaNその他の分類・判定
  • フラグの読み書き
  • その他の演算

[編集] 例外処理

IEEE 754-2008では5種類の例外が定義されている。それぞれ、(確定的なアンダーフローを除いて)対応する状態フラグが存在し、例外発生時には対応するフラグが設定される。それ以外の動作は定義されていないが、他の方法が推奨されている(後述)。

5種類の内訳は以下のとおりである。

  • 無効な演算(負数に対して平方根を求めようとしたなど)
  • 0除算
  • オーバーフロー(結果が正しく表現できないほど大きくなった場合)
  • アンダーフロー(結果が正規数で表現できないほどに小さく非0であるが不正確な結果となった場合)
  • 不正確

これらは、IEEE 754-1985と同一である。

[編集] 関連項目

[編集] 外部リンク

下記はいずれも英文。