Sun Studio 12: Fortran プログラミングガイド

6.2 IEEE 浮動小数点演算

IEEE 演算は、無効演算、ゼロ除算、オーバーフロー、アンダーフロー、結果不正確などの問題を発生させる算術演算を取り扱う、比較的新しい方式です。丸め、ゼロに近い数の扱い方、その機種で取り扱える最大数に近い数の扱い方に違いがあります。

IEEE 規格は、例外、丸め、精度のユーザー処理をサポートします。その結果、IEEE 規格は、区間演算と変則性の診断をサポートします。 IEEE 規格 754 は、expcos などの基本関数の標準化、高精度の演算、数値計算と記号代数計算の結合を実現します。

IEEE 演算では、ほかの浮動小数点演算と比べると、ユーザーが計算を大きく制御できます。IEEE 規格は、数値計算的に洗練された移植性のあるプログラムを作成する作業を簡単にします。浮動小数点演算についての多くの質問は、基本的な数の演算に関連します。たとえば、次のようにします。

もう 1 つのクラスの質問は、浮動小数点例外や例外処理に関連するものです。たとえば、次のとおりです。

旧式の演算モデルでは、最初のクラスの質問は期待された答えにならず、2 番目のク ラスの例外ケースはすべて同じ結果になります。つまり、プログラムは該当する箇所で異常終了するか、演算は続行されるが結果は意味のないものとなります。

IEEE 規格は、演算が数学的に期待される結果を、期待される特性で出すことを保証します。また、ユーザーが特にほかを選択しないかぎり、例外ケースが指定された結果を出すことも保証します。

たとえば、例外値 +Inf、-Inf、NaN は次のように直感的に理解できます。

big*big = +Inf 正の無限大

big*(-big) = -Inf 負の無限大

num/0.0 = +Inf num > 0.0 のとき

num/0.0 = -Inf num < 0.0 のとき

0.0/0.0 = NaN 非数

また、次のような 5 つの種類の浮動小数点例外も発生します。

IEEE 規格の実装については、『数値計算ガイド』を参照してください。

6.2.1 -ftrap=mode コンパイラオプション

-ftrap=mode オプションは、浮動小数点例外用のトラップを有効にします。ieee_handler() 呼び出しによってシグナルハンドラが設定されていない場合、例外はプログラムを終了し、メモリーダンプコアファイルを作成します。このコンパイラオプションに関する詳細は、『Fortran ユーザーズガイド』を参照してください。たとえば、オーバーフロー、ゼロ除算、無効演算のトラップを有効にするには、-ftrap=common を付けてコンパイルします。これが f95 のデフォルトです。


注 –

トラップを有効にするには、アプリケーションの主プログラムを -ftrap= を付けてコンパイルする必要があります。


6.2.2 浮動小数点演算の例外

f95 プログラムは例外を自動的に報告しません。プログラムの終了時に、発生した浮動小数点演算の例外リストを表示するには、ieee_retrospective(3M) を明示的に呼び出す必要があります。一般的には、無効演算、ゼロ除算、オーバーフローのいずれかの例外が発生すると、メッセージが表示されます。実際のプログラムでは結果不正確の例外は多く発生するため、結果不正確の例外のメッセージは表示されません。

6.2.2.1 発生した例外の通知

ieee_retrospective 関数は、浮動小数点のステータスレジスタを調べて、どの例外が発生したのかを突き止め、標準エラーにメッセージを表示し、どの例外が発生してクリアーされていないのかをプログラマに知らせます。 メッセージは通常、次のようになります (リリースによって若干異なります)。


注意: 次の IEEE 浮動小数点例外フラグが立っています:
ゼロ除算;
次の IEEE 浮動小数点例外トラップが有効になっています:
    inexact;  underflow;  overflow;  invalid operation;
『数値計算ガイド』、ieee_flags(3M) のマニュアルページを参照してください
    ieee_handler(3M)

Fortran 95 プログラムでは、ieee_retrospective を明示的に呼び出し、-xlang=f77 を使用してコンパイルして、f77 互換性ライブラリを使用してリンクする必要があります。

-f77 互換性フラグを使用してコンパイルすると、プログラムの終了時に自動的に ieee_retrospective を呼び出す FORTRAN 77 の規則が有効になります。

ieee_retrospective を呼び出す前に例外ステータスフラグをクリアーすると、ieee_flags() を使用して、メッセージの一部また全部を表示させないようにすることができます。

6.2.3 例外処理

IEEE 規格準拠の例外処理は、SPARC および x86 プロセッサ上ではデフォルトで行われます。ただし、浮動小数点例外の検出と、浮動小数点例外に対するシグナル (SIGFPE) の生成には、違いがあります。

浮動小数点演算中にトラップしていない例外が発生すると、IEEE 規格に従って、次の 2 つの処理が行われます。

6.2.4 浮動小数点演算の例外のトラップ

浮動小数点演算の例外を処理する方法は、f95 と以前の f77 では大きく異なります。

f95 のデフォルトでは、ゼロ除算、オーバーフロー、無効演算の場合に自動的にトラップします。f77 のデフォルトでは、浮動小数点演算例外において実行プログラム を中断するためのシグナルを自動的に生成しません。これは、トラップはパフォーマンスを低下させるということと、期待された値が戻ってくれば、ほとんどの例外は重要でないという前提に基づいていました。

f95 のコマンド行オプション -ftrap を使用すると、このデフォルトを変更できます。f95 のデフォルトは -ftrap=common です。以前の f77 のデフォルトに従うには、-ftrap=%none を使用して主プログラムをコンパイルします。

6.2.5 非標準の算術演算

段階的なアンダーフローと呼ばれる、標準の IEEE 算術演算の 1 つは手作業で無効にできます。無効にしたとき、プログラムは非標準の算術演算で実行していると考えられます。

算術演算に関する IEEE 規格では、アンダーフローとなった結果は、有効桁の小数部の基点を動的に調整することにより、段階的に扱うように指定しています。 IEEE の浮動小数点の形式では、有効桁の前に小数点が現れ、暗黙的な 1 の先行ビットがあります。段階的なアンダーフローでは、浮動小数点の演算結果がアンダーフローとなったときに、段階的なアンダーフローでは、暗黙的な先行ビットをゼロにクリアーし、小数点を有効桁方向にシフトさせるようになっています。これは、SPARC プロセッサではハードウェアではなく、ソフトウェアで行われます。このため、プログラムにアンダーフローが多数発生すると (アルゴリズムに問題があることを示す可能性がある)、パフォーマンスが低下することになります。

段階的なアンダーフローを無効にするには、-fns オプションを付けてコンパイルします。または、プログラムの中からライブラリルーチン nonstandard_arithmetic() を呼び出して、段階的なアンダーフローを無効にします。standard_arithmetic() を呼び出して、段階的なアンダーフローを有効に戻します。


注 –

有効にするためには、アプリケーションの主プログラムを -fns を使用してコンパイルする必要があります。『Fortran ユーザーズガイド』を参照してください。


古いアプリケーションの場合、次のことに注意してください。