Oracle® Developer Studio 12.5: 数値計算ガイド

印刷ビューの終了

更新: 2016 年 6 月
 
 

4.2 例外とは

例外を定義することは困難です。W. Kahan 氏によると、

算術演算例外は、試行された不可分な算術演算が、一般に受け入れられるような結果にならなかったときに発生します。不可分と許容の意味は、時間と場所によって異なります。(『Handling Arithmetic Exceptions』、W. Kahan 著を参照してください)。

たとえば、プログラムで負の数の平方根を求めようとすると例外が発生します。この例は、無効な演算例外の一例です。そのような例外が発生した場合、システムは 2 つの方法のいずれかで対応します。

  • 例外のトラップが無効である場合 (デフォルト) は、例外が発生したことがシステムに記録され、IEEE 754 で指定されている例外演算に関するデフォルトの結果を使用して、プログラムの実行が続行されます。

  • 例外のトラップが有効である場合は、SIGFPE シグナルが生成されます。プログラムに SIGFPE シグナルハンドラがインストールされている場合は、そのシグナルハンドラに制御が移ります。シグナルハンドラが設定されていない場合は、プログラムが中止されます。

IEEE 754 は、5 種類の 基本的な浮動小数点例外 (無効な演算、0 による除算、オーバーフロー、アンダーフロー、および不正確) を定義しています。最初の 3 つ (無効な演算、0 による除算、およびオーバーフロー) は、一般的な例外と呼ばれることがあります。通常、これらの例外が発生した場合は無視できません。 ieee_handler(3m) のマニュアルページには、一般的な例外のみをトラップする簡単な方法が説明されています。ほかの 2 つの例外 (アンダーフローと不正確) はより頻繁に確認されます。実際、ほとんどの浮動小数点演算で不正確例外が発生しています。これらの例外は、通常、常にとは言えませんが、安全に無視できます。Oracle Developer Studio 12.5 C、C++、および f77 コンパイラは、デフォルトですべての IEEE トラップを無効にします。f95 コンパイラは、デフォルトで一般的な例外に対してトラップを有効にします。f95 –ftrap=none を指定してコンパイルすると、754 標準に準拠するようになります。

表 31 は、IEEE 規格 754 の情報を要約しています。5 つの浮動小数点例外、およびそれらの例外が発生したときの IEEE 演算環境のデフォルトの応答を示しています。

表 31  IEEE 浮動小数点例外
IEEE
例外
例外の発生理由
デフォルトの結果:
トラップが無効な場合
無効な演算
実行しようとする演算に対してオペランドが無効
(x86 では、浮動小数点スタックがアンダーフローまたはオーバーフローした場合にもこの例外が発生しますが、このことは IEEE 規格には含まれていません。)
  • 0 × ∞

  • 0 / 0

  • ∞ / ∞

  • x REM 0

  • 負のオペランドの平方根

  • シグナルを発生する NaN オペランドを持つ任意の演算

  • 非順序付け比較 (注 1 を参照)

  • 無効な変換 (注 2 を参照)

シグナルを発生しない NaN
0 による除算
有限オペランドに対する演算によって結果が正確な無限数となっている。
  • 有限でゼロでない x に対する x / 0

  • log(0)

正しい符号の 無限大
オーバーフロー
正しく丸めを行なった結果、宛先形式で表現可能な最大有限数よりも絶対値が大きい (つまり、指数範囲を超えた)。
  • 倍精度:

    • DBL_MAX + 1.0e294

    • exp(709.8)

  • 単精度:

    • (float)DBL_MAX

    • FLT_MAX + 1.0e32

    • expf(88.8)

丸めモード (RM) と中間結果の符号に依存する。表 4-1 の注 の項目 4 を参照してください。
アンダーフロー
正確な結果または正しく丸められた結果のどちらも、宛先形式で表現可能な最小の正規数よりも絶対値が小さい (注 3 を参照)。
  • 倍精度:

    • nextafter(min_normal,-·)

    • nextafter(min_subnormal,-·)

    • DBL_MIN §3.0

    • exp(-708.5)

  • 単精度:

    • (float)DBL_MIN

    • nextafterf(FLT_MIN, -·)

    • expf(-87.4)

非正規数または 0
不正確
有効な演算を丸めた結果が、無限に正確な結果と異なる(ほとんどの浮動小数点演算ではこの例外が発生します)。
  • 2.0 / 3.0

  • (float)1.12345678

  • log(1.1)

  • DBL_MAX + DBL_MAX (オーバーフローがトラップされない場合)

演算結果 (丸め、オーバーフロー、またはアンダーフロー)

4.2.1 表 4-1 の注

  1. 非順序付け比較: 任意の浮動小数値のペアは、形式が異なっていても比較できます。次の 4 つの相互に排他的な関係 (より小さい、より大きい、等しい、または非順序付け) があります。非順序付けとは、オペランドのうち少なくとも 1 つが NaN (非数) であることを意味します。

    それぞれの NaN は、その NaN 自体も含めてすべての値に対して「非順序付け」で比較されます。次の表は、関係が非順序付けのときに、無効な演算例外を発生する述語を示しています。

    算術述語
    C、C++ の述語
    Fortran の述語
    無効な式 (非順序付けの場合)
    =
    ==
    .EQ.
    いいえ
    !=
    .NE.
    いいえ
    >
    >
    .GT.
    はい
    >=
    .GE.
    はい
    <
    <
    .LT.
    はい
    <=
    .LE.
    はい
  2. 無効な変換: NaN、または無限大から整数に変換しようとすること、あるいは浮動小数点形式からの変換時に発生した整数値オーバーフロー。

  3. IEEE の単精度、倍精度、および拡張倍精度の形式で表現可能な最小の正規数は、それぞれ 2-126、2-1022、および 2-16382 です。IEEE の浮動小数点形式については、IEEE 演算を参照してください。

  4. 次の表は、オーバーフローに対するトラップが無効にされているときのデフォルトの結果を一覧表示しています。これらの結果は、丸めモードおよび中間結果の符号によって異なります。

    丸めモード
    一番近い値
    +∞
    -∞
    ゼロ
    +∞
    -max
    切り捨て
    +max
    -∞
    切り上げ
    +∞
    -max

x86 浮動小数点環境には、IEEE 規格にはない例外である非正規オペランド例外があります。この例外は、浮動小数点演算が非正規数に対して実行された場合に発生します。

例外は、 次の順序で優先付けされます。無効 (もっとも高い優先度)、オーバーフロー、除算、アンダーフロー、不正確 (もっとも低い優先度)。x86 ベースのシステムでは、非正規オペランド例外はもっとも低い優先度になります。

単一の演算で同時に発生する可能性のある標準例外の組み合わせは、オーバーフローと不正確、およびアンダーフローと不正確のみです。x86 ベースのシステムでは、非正規オペランド例外は 5 つの標準例外のいずれかとともに発生することがあります。 オーバーフロー、アンダーフロー、および不正確のトラップが有効になっている場合は、オーバーフローとアンダーフローのトラップが不正確のトラップよりも優先されます。これらはすべて、x86 ベースのシステムで非正規オペランドのトラップよりも優先されます。