IEEE 754
IEEE 754(IEEE 浮動小数点数演算標準)とは、浮動小数点数の計算で最も広く採用されている標準規格であり、多くのCPUやFPU、またソフトウェアで実装されている。この標準規格は浮動小数点数の表現形式(+0、−0や非正規化数を含む)および特殊な値(無限大やNaN)の表現、浮動小数点演算でのそれらの値の扱い方を規定している。また、5種類の丸め (端数処理) モードと5種類の例外(例外発生時の状況とその後の動作も含む)も規定している。
多くのコンピュータ言語でも、浮動小数点数処理の一部または全部にIEEE 754が採用されている。IEEE 754が制定される前に成立したC言語などは、仕様上はIEEE 754が必須となっていないものの、IEEE 754を採用したコンピュータ・アーキテクチャの普及に伴い、最近の処理系では、自然とIEEE 754が採用されることが多い。一方で、JavaやC#など、言語仕様として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という値を表す。
- 非正規数
- 非正規化数
- 0(+0と−0)
- +∞と−∞。
- 2種類の非数 (NaN)。NaNにはクワイエットNaN (Quiet NaN)とシグナリングNaN (Signaling NaN)が存在する。どちらのNaNでも、追加情報を伝えられる余分のビットが設けられている。
正の有限数は基数 (b) と指数 (p) を基に一意に決定される。そのために指数についてのパラメータemaxを導入して次のようにする。
- cは0からbp−1までの値でなければならない(例えばb = 10 かつ p = 7 ならば c は0から9999999の範囲を取る)。
- qは1−emax ≤ q+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が右)
S は符号、Exp は指数部、Fraction は仮数部である。
指数部はバイアスまたはエクセスと呼ばれる表現形式であり、実際の値にある固定値emax = 127を加算している。このような表現にしているのは浮動小数点数同士の比較を単純にするためである。指数部は大きな値も小さな値も表せるように負の値にもなるが、これを2の補数で表すと、全体の符号 S とは別に Exp も符号を持つことになり、単純な大小比較ができなくなってしまう。そのため、指数部はバイアスされて常に正の値となるような形式で格納される。単精度数の指数部は−126 − +127に127を加えて、1 − 254としている(0と255は特殊な意味を持つ。後述)。浮動小数点数を解釈するときは、バイアスを減算して実際の指数を求める。
表現可能なデータは指数部の値によって区別され、仮数部の値にも影響される。指数部も仮数部も符号無しの二進整数であることに注意されたい(指数部は 0 – 255)。
| 種類 | Exp(指数部) | Fraction(仮数部) |
|---|---|---|
| ゼロ | 0 | 0 |
| 非正規化数 | 0 | 0以外 |
| 正規化数 | 1 – 254 | 任意 |
| 無限大 | 255 | 0 |
| NaN | 255 | 0以外の任意 |
最も一般的な正規化数では、Exp はバイアスされた指数であり、Fraction は仮数の一断片である。先ほどの(−1)s × c × bqと対応づけると次のようになる。
- s = S
- q = Exp − emax (ここではemax = 127であり、換言すれば、指数に127を加算して格納されている。「127でバイアス」しているとも言う)
- b = 2
- c = 1.Fraction
正規数においてcは1以上2未満のため、常に1.xxx…と表記できる。このため、Fractionにはxxx…の部分のみを格納し、実質1ビット多い24ビット精度を実現している。これはけち表現と呼ばれる。
なお、1 − emax = −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”となる。
- 次に、絶対値を二進法で書くと、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)
[編集] 64ビット倍精度
倍精度も、各フィールドの幅が広くなっているだけで、考え方は同じである。
1 11 52 +-+-----------+----------------------------------------------------+ |S| Exp | Fraction | +-+-----------+----------------------------------------------------+ 63 62 52 51 0
正規化数では、指数はemax = +1023でバイアスされる(したがってeはExp − 1023)。正規化数の指数は e: +1023 〜 −1022(Exp: 2046 〜 1)である(Exp = 2047 の時無限大またはNaN、Exp = 0 の時非正規化数で e = −1022)。正規化数の時仮数部はけち表現である。
[編集] 浮動小数点数の比較
浮動小数点数の比較は浮動小数点命令を使うのが最良である。しかし、形式やエンディアンや符号が同じであれば、数値をビット列としてバイト単位に比較することも不可能ではない(NaNは除く)。
ふたつの正の数値aとbについてa < bという比較を行う場合、これを符号無しの整数と見なして比較しても同じ結果を得られる。換言すれば、(NaN以外の)2つの正の浮動小数点数は符号無し整数として比較できる(ただし、エンディアンが異なる場合は比較できないので、移植性が問題となるコードで共用体を使ってこれをするのはお勧めできない)。これは辞書式順序の例である。
[編集] 十進浮動小数点数
十進浮動小数点数に対しては、32の倍数のビット数での交換形式が定義されている。
二進の場合と同様、符号、指数、仮数と符号化していくが、仮数部は十進の各桁をより詰め込めるよう、BCDなどではなく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と同一である。
[編集] 参考文献
- IEEE 754 http://grouper.ieee.org/groups/754/
[編集] 関連項目
[編集] 外部リンク
下記はいずれも英文。
- Floating Point Unit by Jidan Al-Eryani
- IEEE 754 references
- Let's Get To The (Floating) Point by Chris Hecker
- What Every Computer Scientist Should Know About Floating-Point Arithmetic by David Goldberg
- The pitfalls of verifying floating-point computations
- IEEE 854-1987 履歴と覚書
- Web Based Converter
- Another Web Based Converter
- Java Applet Converter
- Converter as MS-Windows program
- An Interview with the Old Man of Floating-Point
- Coprocessor.info : x87 FPU pictures, development and manufacturer information
|
||||||||||||||