ieee_flags 関数は、例外ステータスフラグの問い合わせやクリアーに使用します。この関数は、Sun コンパイラとともに出荷される libsunmath ライブラリに組み込まれていて、次の作業を行うことができます。
丸めの方向と丸めの精度の制御
例外ステータスフラグの検査
例外ステータスフラグのクリアー
ieee_flags の一般的な呼び出し方法は次のとおりです。
flags = ieee_flags( action, mode, in, out ) |
4 つの引数はすべて文字列です。入力は、action、mode、および in です。出力は、out と flags です。ieee_flags は、整数値の関数です。flags は 1 ビットフラグの集合で、ここには有用な情報が返されます。詳細は、ieee_flags(3m) のマニュアルページを参照してください。
表 6–1 ieee_flags( action, mode, in, out ) の引数の値
引数の |
使用可能な値 |
---|---|
action |
get、set、clear、clearall のいずれか |
mode |
direction、exception |
in、out |
nearest、tozero、negative、positive、extended、double single、inexact、division、underflow、overflow、invalid all、common |
これらはリテラル文字列であること、出力パラメータ out は最低でも CHARACTER*9 である必要があることに注目してください。in と out の取り得る値の意味は、使用時の動作とモードによって異なります。これらの関係を次の表に要約します。
表 6–2 ieee_flags の引数 in と out の意味
in と out の値 |
意味 |
---|---|
nearest、tozero、negative、positive |
丸めの方向 |
extended、double、single |
丸めの精度 |
inexact、division、underflow、overflow、invalid |
例外 |
all |
5 種類すべての例外 |
common |
一般的な例外: invalid (無効演算)、division (ゼロ除算)、overflow (オーバーフロー) |
たとえば、フラグが立てられている例外のうちで何がもっとも優先順位が高いかを判別するときは、引数の in に NULL 文字列を渡します。
CHARACTER *9, out ieeer = ieee_flags( 'get', 'exception', '', out ) PRINT *, out, ' flag raised' |
また、overflow 例外フラグが立てられているかどうかを判別するときは、引数の in に overflow を設定します。復帰時に、out が overflow になっていれば、overflow 例外のフラグが立てられているということです。
ieeer = ieee_flags( 'get', 'exception', 'overflow', out ) IF ( out.eq. 'overflow') PRINT *, 'overflow flag raised' |
例: invalid 例外をクリアーします。
ieeer = ieee_flags( 'clear', 'exception', 'invalid', out ) |
例: すべての例外をクリアーします。
ieeer = ieee_flags( 'clear', 'exception', 'all', out ) |
例: ゼロに近づけるように丸めます。
ieeer = ieee_flags( 'set', 'direction', 'tozero', out ) |
例: 丸めの精度を double に設定します。
ieeer = ieee_flags( 'set', 'precision', 'double', out ) |
次の例のように、動作 clear で ieee_flags を呼び出すと、クリアーされてない例外すべてがリセットされます。 プログラムが終了する前にこの呼び出しを置くと、プログラム終了時の浮動小数点例外に関するシステム警告メッセージを抑制します。
例: ieee_flags() を使用して、発生していたすべての例外をクリアーします。
i = ieee_flags('clear', 'exception', 'all', out ) |
次の例は、前の計算によってどの浮動小数点例外フラグが立ったかを決定する方法を示しています。システム include ファイル floatingpoint.h に定義されたビットマスクは、ieee_flags により返された値に適用されます。
この例 DetExcFlg.F では、インクルードファイルは #include 前処理部指令を使用して導入されます。 この指令には、.F 接尾辞のソースファイルを指定しなければいけません。アンダーフローの原因は、最小の倍精度数を 2 で除算しているためです。
例: ieee_flags を使用して例外を検出し、復号化します。
#include "floatingpoint.h" CHARACTER*16 out DOUBLE PRECISION d_max_subnormal, x INTEGER div, flgs, inv, inx, over, under x = d_max_subnormal() / 2.0 ! アンダーフローを発生 flgs=ieee_flags('get','exception','',out) ! どの例外が発生したのか ? inx = and(rshift(flgs, fp_inexact) , 1) ! ieee_flags div = and(rshift(flgs, fp_division) , 1) ! によって under = and(rshift(flgs, fp_underflow), 1) ! 返される over = and(rshift(flgs, fp_overflow) , 1) ! 値を inv = and(rshift(flgs, fp_invalid) , 1) ! 復号化 PRINT *, "もっとも優先順位が高い例外:", out PRINT *, ' invalid divide overflo underflo inexact' PRINT '(5i8)', inv, div, over, under, inx PRINT *, '(1 = 例外フラグが立っている; 0 = 立っていない)' i = ieee_flags('clear', 'exception', 'all', out) ! すべてクリアー END |
例: 前出の例 (DetExcFlg.F) をコンパイルして実行します。
demo% f95 DetExcFlg.F demo% a.out もっとも優先順位が高い例外: underflow invalid divide overflo underflo inexact 0 0 0 1 1 (1 = 例外フラグが立っている; 0 = 立っていない) demo% |