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

印刷ビューの終了

更新: 2015 年 1 月
 
 

4.3.1 ieee_flags(3m)

ieee_flags は、Oracle Solaris Studio C、C++、および Fortran に似ている IEEE 754 例外フラグのインタフェースを提供しています。ただし、このインタフェースは Oracle Solaris OS でのみ使用できます。より幅広く移植できるようにする C および C++ プログラムには、C99 例外フラグ関数を使用してください。

ieee_flags(3m) を呼び出す構文は次のとおりです。

i = ieee_flags(action, mode, in, out);

プログラムで累積例外ステータスフラグをテスト、設定、またはクリアするには、文字列 "exception" を 2 番目の引数として指定して ieee_flags 関数を使用します。たとえば、Fortran でオーバーフロー例外フラグをクリアするには、次のように記述します。

      character*8 out
      call ieee_flags('clear', 'exception', 'overflow', out) 

C または C++ で、例外が発生したかどうかを判別するには、次のように記述します。

      i = ieee_flags("get", "exception", in, out); 

action が "get" の場合に out に返される文字列は、次のいずれかです。

  • "not available" — 例外に関する情報を取得できない場合

  • "" (空白の文字列) — 累積例外が一度も発生していない場合、または x86 の場合は、非正規オペランドが唯一の累積例外であるとき

  • 例外が発生した場合は、3 番目の引数 in に指定されている例外の名前が返されます

  • そうでない場合は、発生したもっとも高い優先順位を持つ例外の名前

たとえば、次の Fortran の呼び出しで 0 による除算の例外が発生した場合、out に返される文字列は "division" になります。それ以外の場合は、発生したもっとも優先順位の高い例外の名前です。

      character*8 out
      i = ieee_flags('get', 'exception', 'division', out)

in に特定の例外が指定されてない場合、in は無視されます。たとえば、次の C の呼び出しでは引数 "all" は無視されます。

      i = ieee_flags("get", "exception", "all", out); 

out に例外の名前を返すことに加えて、ieee_flags は、現在発生している例外フラグをすべて組み合わせた整数値も返します。この値は、すべての累積例外フラグのビット単位の「or」であり、各フラグは Table 4–2 に示されているように単一のビットで表されます。各例外に対応するビットの位置は、sys/ieeefp.h ファイルに定義されている fp_exception_type 値によって示されています(これらのビットの位置はマシンによって異なり、連続しているとは限りません)。

表 4-2  例外ビット
例外
ビットの位置
累積例外ビット
invalid
fp_invalid
i & (1 << fp_invalid)
overflow
fp_overflow
i & (1 << fp_overflow)
division
fp_division
i & (1 << fp_division)
underflow
fp_underflow
i & (1 << fp_underflow)
inexact
fp_inexact
i & (1 << fp_inexact)
denormalized
fp_denormalized
i & (1 << fp_denormalized) (x86 のみ)

次の C または C++ のプログラムの一部は、戻り値をデコードする 1 つの方法を示しています。

/*
 *   Decode integer that describes all accrued exceptions. 
 *   fp_inexact etc. are defined in <sys/ieeefp.h> 
 */ 
 
char *out; 
int invalid, division, overflow, underflow, inexact; 
 
code = ieee_flags("get", "exception", "", &out); 
printf ("out is %s, code is %d, in hex: 0x%08X\n", 
  out, code, code); 
inexact  =  (code >> fp_inexact) & 0x1; 
division  =  (code >> fp_division) & 0x1; 
underflow  =  (code >> fp_underflow) & 0x1; 
overflow  =  (code >> fp_overflow) & 0x1; 
invalid  =  (code >> fp_invalid) & 0x1; 
printf("%d %d %d %d %d \n", invalid, division, overflow,
  underflow, inexact);