EN JA
IEEE(3)
IEEE(3) FreeBSD Library Functions Manual IEEE(3)

名称

ieeeIEEE 標準 754 浮動小数点算術演算

解説

IEEE 標準 754 バイナリ浮動小数点算術演算は、以下で説明されるように、浮動小数点数の表現と精度に関連する四則演算の抽象的な特性、丸め、および例外を定義します。
 
訳注: 数学用語の翻訳が間違っているかもしれません。

IEEE 標準 754 浮動小数点算術演算

基数: バイナリ。

オーバフローとアンダフロー:

オーバフローは、デフォルトで符号付きの無限 (infinity) になります。アンダフローは、 グラデュアル (段階的) です。訳注: IEEE 754 のグラデュアル・アンダフローを参照。

0 は、+0 か-0 のようにあいまいに表現されます。

その符号は、乗算と除算で正確に変換し、等式の 0 の加算によって保存されています。しかし、すべての有限の x では x-x は、+0 をもたらします。 0 の符号を明らかにするただ一つの演算は、0 の除算と copysign( x, ±0) です。特に、(x > y, x ≥ y などの) 比較は、0 の符号から影響を受けませんが、有限の x = y である場合、infinity = 1/(x-y) ≠-1/(y-x) = -infinity になります。

infinity (無限) は、符号付きです。

それ自体か任意の有限の数値に加算された時でも、無限は、持続します。無限 (infinity) の符号は、乗算と除算で正確に変換し、 (有限値)/±infinity = ±0 (非 0 値)/0 = ±infinity になります。しかし、 infinity-infinity, infinity∗0, infinity/infinity は、0/0 や sqrt(-3) のように NaN を生成する無効演算です。...

予約オペランド (NaN):

NaN は、 ( Not a Number (数でない)) です。 Signaling NaN と呼ばれるいくつかの NaN は、それに対して浮動小数点演算を実行するとトラップが発生します。それらは、不足した値か未初期化の値、または存在しない配列要素をマークするために使用されます。残りは、Quiet NaN です。これは、無効演算のデフォルトの結果であり、後の算術演算で伝搬します。 x ≠ x である場合、x は、NaN です。 NaN が関係する場合は、他のすべての述語 (論理演算?) (x > y, x = y, x < y など) は、FALSE (偽) です。

丸め:

すべての代数演算 (+, -, ∗, /, √) は、 ulp の半分以内にデフォルトで丸められます。丸め誤差が ulp のちょうど半分である場合、丸めた値の最下位ビットは、0 になります。 ( ulp は、one Unit in the Last Place (???) です。) 訳注: 訳不明。このような丸めは、通常最良のものであり、時々はそうと証明可能です。例えば、すべての x = 1.0, 2.0, 3.0, 4.0, ..., 2.0**52 について、商と積の両方が丸められるにもかかわらず、 (x/3.0)∗3.0 == x、(x/10.0)∗10.0 == x、... です。 IEEE 754 のような丸めのみそれができます。しかし、1 種類の丸めがあらゆる状況で最良であるとは証明できません。したがって、IEEE 754 は、プログラマのオプションで、0 の方へ、 +infinity の方へ、-infinity の方への丸めを提供します。

例外:

IEEE 754 は、重要と思われる順序で次にリストした、5 種類の浮動小数点例外を認識します。
例外 デフォルトの結果
無効演算 NaN または FALSE (偽)
オーバフロー ±infinity (無限)
0 除算 ±infinity (無限)
アンダフロー グラデュアルアンダフロー
不正確 丸め値

注: 下手に処理されない限り、例外は、エラーではありません。例外の集合が例外的であるのは、1 つのデフォルトレスポンスですべての例を満足することができないためです。一方、デフォルトレスポンスがほとんどの例を満足させるのであれば、不満足な例は、例外が生じるたびに演算処理を異常終了させることを正当化することはできません。

データ形式

単精度 (Single-precision):
タイプ名: float

ワードサイズ: 32 ビット。

精度: 24 有効桁数ビット、約 7 有効桁数 10 進数。

x と x' が連続する正の単精度数 (1 ulp で異なる) である場合は、

5.9e-08 < 0.5**24 < (x'-x)/x ≤ 0.5**23 < 1.2e-07 となります。

範囲: オーバフローしきい値 = 2.0**128 = 3.4e38
アンダフローしきい値 = 0.5**126 = 1.2e-38

アンダフローの結果は、次の倍数の最も近い整数に丸められます。

0.5**149 = 1.4e-45.

倍精度 (Double-precision):

タイプ名: double (いくつかのアーキテクチャでは、 long double は、 double と同じです。)

ワードサイズ: 64 ビット。

精度: 53 有効桁数ビット、約 16 有効桁数 10 進数。

x と x' が連続する正の倍精度数 (1 ulp で異なる) である場合は、

1.1e-16 < 0.5**53 < (x'-x)/x ≤ 0.5**52 < 2.3e-16

となります。

範囲: オーバフローしきい値 = 2.0**1024 = 1.8e308
アンダフローしきい値 = 0.5**1022 = 2.2e-308

アンダフローの結果は、次の倍数の最も近い整数に丸められます。

0.5**1074 = 4.9e-324

拡張精度 (Extended-precision):

タイプ名: long double (ハードウェアによってサポートされた時)

ワードサイズ: 96 ビット。

精度: 64 有効桁数ビット、約 19 有効桁数 10 進数。

x と x' が連続する正の拡張精度数 (1 ulp で異なる) である場合は、

1.0e-19 < 0.5**63 < (x'-x)/x ≤ 0.5**62 < 2.2e-19.

となります。

範囲: オーバフローしきい値 = 2.0**16384 = 1.2e4932
アンダフローしきい値 = 0.5**16382 = 3.4e-4932

アンダフローの結果は、次の倍数の最も近い整数に丸められます。

0.5**16445 = 5.7e-4953

4 倍拡張精度 (Quad-extended-precision):

タイプ名: long double (ハードウェアによってサポートされた時)

ワードサイズ: 128 ビット。

精度: 113 有効桁数ビット、約 34 有効桁数 10 進数。

x と x' が連続する正の 4 倍拡張精度数 (1 ulp で異なる) である場合は、

9.6e-35 < 0.5**113 < (x'-x)/x ≤ 0.5**112 < 2.0e-34.

となります。

範囲: オーバフローしきい値 = 2.0**16384 = 1.2e4932
アンダフローしきい値 = 0.5**16382 = 3.4e-4932

アンダフローの結果は、次の倍数の最も近い整数に丸められます。

0.5**16494 = 6.5e-4966.

例外に関する追加情報

各種の浮動小数点の例外について、 IEEE 754 では、その例外が発生するたびに上げられ、プログラムがそれをリセットするまで上げられた状態となるフラグを提供します。プログラムは、さらにフラグをテストし、保存し、復旧できます。したがって、IEEE 754 では、デフォルト結果が不満足かもしれない例外にプログラムが対処する 3 つの方法を提供します。
  1. 後で例外を起こす条件をテストし、例外を回避するために分岐します。
  2. プログラムが最後にそのフラグをリセットしてから例外が発生したどうか確かめるためにフラグをテストします。
  3. 1 つの例外だけを生成する値かどうか確かめるために結果をテストします。

    警告: アンダフローが発生したかどうか発見する唯一の信頼できる方法は、積や商がアンダフローしきい値より 0 に近い状態かどうかテストするか、アンダフローフラグをテストすることです。 (IEEE 754 では、和と差がアンダフローを起こすことはありません。 x ≠ y である場合、x-y は、完全に正確で、どれくらい小さいかにかかわらず確かに 0 でないかもしれません。) 段階的なアンダフローを起こす積と商は、消滅することなしに段階的に精度を失うことができます。したがって、0 とそれらを比較することは (VAX ではできるように) ロスを明らかにしません。幸運にも、グラデュアル (段階的) アンダフローした値がアンダフローしきい値より大きいものに加算される場合、これは、ほとんど常に当てはまるのですが、それらがとにかく丸められたので、グラデュアルアンダフローで失われた数は、不足しません。それで、グラデュアルアンダフローは、通常無視できることが 証明可能 です。同じことは、0 にフラッシュされるアンダフローについては言えません。

IEEE 754 に準拠するメーカのオプションでは、次のように例外に対処する他の方法が提供されるかもしれません:

  1. 異常終了 (ABORT)。このメカニズムは、"ON ERROR GO TO ..."のようなエラー操作ステートメントにもともと関連した方法によって処理される出来事として、例外を前もって分類します。異なる言語は、このステートメントと異なった形式を提示しますが、たいていのものは、次の特性を共有します。
    • 原因となった演算の結果の値を代用し、式の途中かもしれないものからの計算を再開する方法は、提供されません。例外の結果は、放棄されます。
    • エラー操作ステートメントを欠くサブプログラムでは、それを呼び出したすべてのプログラムは、なんでも例外がサブプログラムを異常終了させます。その他、エラー操作ステートメントに遭遇するか、全体のタスクが異常終了しメモリがダンプされるまで、一連のサブプログラムの呼び出しをバックアップします。
  2. 停止 (STOP)。対話型のデバッグ環境を要求するこのメカニズムは、プログラムよりもプログラマにとってのものです。それは、プログラマのエラーの徴候として例外を前もって分類します。プログラマが、それがどのように起こったか確かめて見回すことができるように、例外は、原因となる操作にできるだけ近い実行を保留 (サスペンド) します。かなり頻繁に、最初のいくつかの例外は、結局全く問題がないことが分かります。したがって、プログラマは、あたかも実行が止められなかったかのように、各々の後に実行を理想的に再開することができるようすべきです。
  3. ... その他の方法については、この文書の範囲外です。

理想的には、それぞれの初等関数は、次のような意味であたかもそれが分割不可能か不可分のように、作用するべきです。

  1. その関数に供給されたデータに価値がない例外は、発生させてはなりません。
  2. 発生したどんな例外も、そのサブルーチンのうちの 1 つではなくその関数と識別されるべきです。
  3. 関数の定義は、故意に例外処理と関連させられますが、呼び出しプログラムが、上に挙げられた 5 つ程度の例外処理の方法を別のものに変更する場合、不可分な関数の内部の振る舞いを分裂してはなりません。

libm 中の関数のみほぼ不可分です。多分次の場合を除き、それらは、不適当な例外を発生させません。

オーバフロー/アンダフロー
適切に計算された結果が範囲内にかろうじて収まる場合、および、
cabs(), cbrt(), hypot(), log10(), pow() での不正確
誤差の偶然の打ち消し合いで、たまたま正確になった場合。

そうでなければ ...

無効演算は、次の場合にのみ発生します。
NaN 以外のどんな結果も誤解を招くかも知れない場合。
オーバフローは、次のような場合にのみ発生します。
正確な結果は、有限で、しかしオーバフローしきい値を越えている場合。
0 除算は、次のような場合にのみ発生します。
関数は、有限のオペランドで正確に無限の値をとる場合。
アンダフローは、次のような場合にのみ発生します。
正確な結果は、ゼロにならないで、しかしアンダフローしきい値より小さい場合。
不正確は、次のような場合にのみ発生します。
より広い範囲か精度が正確な結果を表わすために必要である場合。

関連項目

fenv(3), ieee_test(3), math(3)

IEEE 754 およびその提案された拡張 p854 の説明は、 W. J. Cody らによる "A Proposed Radix- and Word-length-independent Standard for Floating-point Arithmetic" (浮動小数点演算のための提案された基数およびワード長独立標準) という題名で 1984 年 8 月に IEEE マガジン MICRO で発行されました。 Apple Macintosh (アップルマッキントッシュ) の Pascal、C および BASIC のマニュアルは、IEEE 754 の特徴をかなりよく文書化しています。 IEEE マガジン COMPUTER vol. 14 no. 3 (1981 年 3 月) の記事、および 1979 年 10 月の ACM SIGNUM Newsletter Special Issue は、とって代わられた標準案に関係しますが有用です。

規格

IEEE Std 754-1985
January 26, 2005 FreeBSD