Oracle® Solaris Studio 12.4: 数値計算ガイド

印刷ビューの終了

更新: 2015 年 1 月
 
 

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 Solaris Studio 12.4 C、C++、および f77 コンパイラは、デフォルトですべての IEEE トラップを無効にします。f95 コンパイラは、デフォルトで一般的な例外に対してトラップを有効にします。f95 –ftrap=none を指定してコンパイルすると、754 標準に準拠するようになります。

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

表 4-1  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 (オーバーフローがトラップされない場合)

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