/fpe オプションの結果は、作成しているアプリケーションの形式によって異なります。Fortran コンソールまたは QuickWin/スタンダード・グラフィックス・アプリケーションで選択されたオプションが、デフォルトのランタイム例外処理を無効にしないと仮定される場合のみ、完全な結果が得られます。完全な結果を得るための作業は、デフォルトのランタイムハンドラー、Fortran コンパイラー、算術ライブラリー、ハードウェア、およびオペレーティング・システムのそれぞれで行われます。
コンソール・アプリケーションをビルドするとき、コンパイラーは Fortran メインプログラムの最初に、デフォルトオプションまたは選択したコンパイル時のオプションに従って、環境を初期化する Fortran ランタイムルーチンへの呼び出しを生成します。
浮動小数点例外処理では、/fpe:3 がデフォルトです。ランタイムシステムはすべての例外をマスクするようにハードウェアを初期化します。/fpe:3 の動作は次のとおりです。
インテル® Fortran ランタイムシステムは、この初期化を (コンパイルされたコードからの呼び出しなしで) 自動的に行います。
IA-32 アーキテクチャー・ハードウェアは例外結果用にデフォルトの IEEE 結果を自動的に生成します。
トラップは /fpe:3 ではマスクされるため、トラップは発生せず、演算結果は NaN、無限大、正規化されていない数のような例外値になります。
ユーザーは、GETSTATUSFPQQ を使用して浮動小数点ステータスワードを調査し、例外が発生したかどうかを調べることができます。ステータスレジスターをクリアするには、CLEARSTATUSFPQQ を使用します。
/fpe:0 を指定すると、コンパイラーは浮動小数点コントロール・ワードですべての浮動小数点トラップをマスク解除する引数を指定して、インテル® Fortran ランタイムルーチン FOR_SET_FPE への呼び出しを生成します。この場合、ハードウェアはデフォルトの IEEE 結果を生成しません。ハードウェアは、オペレーティング・システムをトラップした後、条件ハンドラーを探します。
Fortran コンソールまたは Fortran QuickWin アプリケーションでは、独自の条件ハンドラーを確立しない限り、インテル® Fortran ランタイムシステムはデフォルトの条件ハンドラーを提供します。アンダーフロー以外の例外の場合、ランタイムシステムはエラーメッセージを表示してアプリケーションを終了します。アンダーフローの場合、ランタイムシステムは結果をゼロにします。/fpe:0 を指定したアンダーフローの処理は、突発アンダーフロー (abrupt underflow) と呼ばれ、0 (ゼロ) になります。その逆の漸次アンダーフロー (gradual underflow) は、/fpe:3 を指定した場合にゼロになります。
アンダーフローの結果をゼロに修正する処理が行われると、IA-32 アーキテクチャーをベースとしたアプリケーションのパフォーマンスは大幅に低下します。アンダーフローが頻繁に発生する場合、アンダーフローが発生しないようにコードを変更するか、アンダーフロー・トラップをマスクしてハードウェアが正規化されていない数を処理できるようにすることを考慮してください。IA-32 アーキテクチャー・ベースのハードウェアは、正規化されていない範囲で正確に動作するように設計されているため、結果をゼロに修正するトラップ処理を行うよりもはるかに高速に動作します。
/fpe オプションの選択に関して知っておくべき別の重要なポイントは、生成されたコードがトラッピング・モードを必ずサポートしなければならないという点です。IA-32 アーキテクチャー・ベースの浮動小数点命令が例外結果を生成するときに、トラップを得る必要はありません。命令は、トラップが発生するように、fwait 命令または別の浮動小数点演算命令に続けなければなりません。
インテル® Fortran コンパイラーは、/fpe オプションの選択に関連するこれらの要求をサポートするマシンコードを生成します。つまり、生成されたコードはトラッピング・モードをサポートしなければなりません。これは、簡単なテストプログラムを作成し、最初に /fpe:0、次に /fpe:3 を指定してコンパイルし、生成されるマシンコードを見るとよくわかります。/fpe:3 を指定した場合、fwait 命令はありません。デフォルトのランタイム例外ハンドラーを独自のハンドラーに変更した場合でも、トラッピングをサポートするコードを生成するように、/fpe:0 を指定してコンパイルすることができます。
DLL には、(Fortran でメインプログラムを作成しなければ) メインの Fortran プログラムはありません。このため、環境を初期化するランタイムルーチンが自動的に呼び出されることはありません。/fpe:0 を選択した場合でも、ランタイムシステムがハードウェアでトラップをマスク解除することはないため、トラップは発生しません。ハードウェアが生成したデフォルトの IEEE 結果 (演算で NaN、無限大、正規化されていない数) が表示され続けることになります。生成されたコードは、fwait 命令などを提供して部分的にその役割を果たしますが、トラップがマスク解除されない限り、トラップは発生しません。SETCONTROLFPQQ または FOR_SET_FPE を使用して、浮動小数点コントロール・ワードでトラップをマスク解除することができます。
DLL には、デフォルトの例外処理もありません。DLL を呼び出すメイン・アプリケーションが提供するか、DLL のコードが呼び出されたときに何かを提供しなければなりません。アンダーフロー処理 (ゼロに修正など) はデフォルトの Fortran ランタイム・システム・ハンドラーで行われるため、DLL には処理を自動的に行う機能はありません。
一般的な方法は /fpe:0 を指定してコンパイルすることですが、この方法は、ゼロによる浮動小数点除算、浮動小数点オーバーフロー、および無効な浮動小数点の浮動小数点コントロール・ワードにおけるトラップのみをマスク解除します。浮動小数点アンダーフロー・トラップをマスクしたままにしておくことで、ハードウェアは漸次アンダーフロー (gradual underflow) を提供し続けます。しかし、他の浮動小数点例外はトラップを生成するため、ユーザーは必要に応じて処理することができます。
Fortran Windows アプリケーションは、Fortran DLL アプリケーションの状況と似ています。アプリケーションのメイン・エントリー・ポイントとして、Fortran コードで WinMain ルーチンを定義します。Fortran ランタイムシステムは、Fortran コンソールや Fortran QuickWin (またはスタンダード・グラフィックス) アプリケーションで行ったメインルーチンの定義を行いません。コードはデフォルトハンドラーで保護されず、デフォルトのランタイム初期化ルーチンは呼び出されません。