IEEE 754 浮動小数点数
この章の目標
第1章で学んだ浮動小数点数の基礎を前提に、IEEE 754 規格の詳細 — 規格の歴史と規定内容、NaN の 2 種類(qNaN / sNaN)、符号付きゼロの性質、段階的アンダーフロー、正しい丸め(correctly rounded)の保証 — を理解する。
前提知識
- 2進数の基礎(ビット、バイト)
- 浮動小数点数の基本概念
1. 概要
IEEE 754(正式名称: IEEE Standard for Floating-Point Arithmetic)は、浮動小数点演算の国際標準規格である。1985年に初版が策定され(IEEE 754-1985)、2008年に改訂(IEEE 754-2008)、2019年に最新版(IEEE 754-2019)が発行された。
現在のほぼすべてのプロセッサ(CPU、GPU)がこの規格の形式と演算を実装しており、プログラミング言語の float(単精度)や double(倍精度)はこの規格に基づいている。ただし、高速化のために非正規化数を 0 に置き換える設定(flush-to-zero)など、規格どおりに動かない動作モードを持つ環境もある(§3 の性質はこのモードでは成り立たない)。
IEEE 754-2008 では、単精度(32ビット)・倍精度(64ビット)に加えて四倍精度(128ビット)が演算の基本形式として、半精度(16ビット)が主にデータ交換用の形式として規定されている。
IEEE 754 が規定するもの
- 数の表現形式(符号・指数・仮数のビット構成)
- 特殊値($\pm\infty$, NaN, $\pm 0$)
- 丸め規則(5種類の丸めモード)
- 基本演算($+, -, \times, \div, \sqrt{\phantom{x}}$)の正確な丸めの保証
- 例外処理(無効操作、ゼロ除算、オーバーフロー、アンダーフロー、不正確)
2. 特殊値の詳細
特殊値の基本(指数部と仮数部の組合せ)は第1章 §4で解説した。ここでは実用上重要な詳細を補足する。
NaN の 2 種類
NaN には quiet NaN(qNaN)と signaling NaN(sNaN)の2種類がある。qNaN は算術演算の入力になっても例外を発生させず、結果の NaN としてそのまま伝播する。ただし大小比較($\lt$, $\le$, $\gt$, $\ge$)では、qNaN でも無効演算の例外が発生する(例外を発生させない版の比較も規格にある)。sNaN は、ほとんどの演算で入力として使われた時点で無効演算の例外を発生させる。
NaN の判定には、各言語の isnan 相当の関数(C の isnan、Python の math.isnan など)を使うのが確実である。等価比較 x == x が NaN のときだけ false になる性質でも判定できるが、コンパイラの高速化オプション(-ffast-math など)では NaN が現れない前提で最適化され、この判定が消えることがある:
x = 0.0 / 0.0 // NaN
x == x // false(NaN の検出に使える)
x != x // true
符号付きゼロ($\pm 0$)の性質
$+0$ と $-0$ は比較では等しい($+0 == -0$ は true)が、$1/(+0) = +\infty$, $1/(-0) = -\infty$ と区別される。
3. 段階的アンダーフロー
非正規化数(サブノーマル数)により、最小正規化数とゼロの間のギャップが埋められ、段階的アンダーフロー(gradual underflow)が実現される。
非正規化数は正規化数より有効桁数が少ないが、$\text{fl}(x - y) = 0 \Rightarrow x = y$ という重要な性質を保証する($\text{fl}$ は浮動小数点数への丸め)。非正規化数がなければ、異なる値 $x \neq y$ に対して $\text{fl}(x - y) = 0$ となるケースが発生し、たとえば「$x \neq y$ を確かめてから $1/(x - y)$ を計算する」処理がゼロ除算を起こす。非正規化数を 0 に置き換える設定(flush-to-zero)では、この性質は成り立たない。
4. 正しい丸めの保証
IEEE 754 では、基本演算($+, -, \times, \div, \sqrt{\phantom{x}}$)の結果が正しく丸められる(correctly rounded)ことが保証される。すなわち、結果は「無限精度で演算を行い、その結果を丸めた値」と一致する。
丸めモードの種類は第1章 §6で列挙している。デフォルトは最近接偶数丸め(round to nearest, ties to even)である。
この「正しい丸め」により、上の基本演算 $\circ \in \{+, -, \times, \div\}$ の結果は、オーバーフローもアンダーフローも起きない範囲(厳密な結果の絶対値が正規化数の範囲に収まるとき)で、既定の最近接偶数丸めのもとで
$$\text{fl}(a \circ b) = (a \circ b)(1 + \delta), \quad |\delta| \le u = \frac{\varepsilon_{\text{mach}}}{2}$$と表される。$u$ は第3章で扱う丸めの単位(unit roundoff)で、倍精度では $u = 2^{-53} \approx 1.11 \times 10^{-16}$、計算機イプシロンは $\varepsilon_{\text{mach}} = 2^{-52}$ である。範囲の外では成り立たない(たとえば $2^{-1060} \times 2^{-1060}$ は 0 に丸められ、$\delta = -1$ になる)。この性質は数値安定性の解析の基盤であり、誤差解析において繰り返し用いられる。
5. よくある質問
Q1. IEEE 754 とは何か
浮動小数点演算の国際標準規格であり、数の表現形式、丸め規則、特殊値、例外処理を規定している。1985年に初版が策定され、現在のほぼすべてのプロセッサがこの規格に準拠している。
Q2. 倍精度浮動小数点数の有効桁数は何桁か
仮数部は52ビット(暗黙の1ビットを含めて53ビット)であり、10進数で約15〜16桁の有効数字に相当する。計算機イプシロン(1 と、1 の次に大きい浮動小数点数との差)は $2^{-52} \approx 2.22 \times 10^{-16}$ で、丸めの単位 $u$ はその半分の $2^{-53} \approx 1.11 \times 10^{-16}$ である。
Q3. NaN とは何か
$0/0$、$\infty - \infty$、$\sqrt{-1}$ など、実数の浮動小数点演算として値が定まらない演算の結果を表す特殊値である。NaN は自分自身を含むどの値とも大小関係が付かず、$=$, $\lt$, $\le$, $\gt$, $\ge$ の比較はすべて false、$\neq$ だけが true になる($\text{NaN} \neq \text{NaN}$ も true)。
6. 参考資料
- Wikipedia「IEEE 754」(日本語版)
- Wikipedia「IEEE 754」(英語版)
- Wikipedia「Double-precision floating-point format」(英語版)
- D. Goldberg, "What Every Computer Scientist Should Know About Floating-Point Arithmetic," ACM Computing Surveys, vol. 23, no. 1, pp. 5–48, 1991.
- IEEE 754-2019, IEEE Standard for Floating-Point Arithmetic, IEEE, 2019.
- M. L. Overton, Numerical Computing with IEEE Floating Point Arithmetic, SIAM, 2001.
sangi での実装
IEEE 754 の特殊値(NaN・無限大)の判定や丸めモードの指定は sangi の Float クラス で利用できる。