EN JA
FENV(3)
FENV(3) FreeBSD Library Functions Manual FENV(3)

名称

feclearexcept, fegetexceptflag, feraiseexcept, fesetexceptflag, fetestexcept, fegetround, fesetround, fegetenv, feholdexcept, fesetenv, feupdateenv, feenableexcept, fedisableexcept, fegetexcept浮動小数点環境の制御

ライブラリ

Math Library (libm, -lm)

書式

#include < fenv.h>

#pragma STDC FENV_ACCESS ON

int
feclearexcept( int excepts);

int
fegetexceptflag( fexcept_t *flagp, int excepts);

int
feraiseexcept( int excepts);

int
fesetexceptflag( const fexcept_t *flagp, int excepts);

int
fetestexcept( int excepts);

int
fegetround( void);

int
fesetround( int round);

int
fegetenv( fenv_t *envp);

int
feholdexcept( fenv_t *envp);

int
fesetenv( const fenv_t *envp);

int
feupdateenv( const fenv_t *envp);

int
feenableexcept( int excepts);

int
fedisableexcept( int excepts);

int
fegetexcept( void);

解説

< fenv.h> ルーチンは、 IEEE Std 754-1985 で定義された例外フラグと丸めモードを含んで、浮動小数点環境を操作します。

例外

例外フラグは、浮動小数点の四則演算と数学ライブラリルーチンの副作用として設定され、それらは、明示的にクリアされるまで設定されたままとなります。次のマクロは、5 つの標準の浮動小数点の例外を表す int タイプのビットフラグを展開します。
FE_DIVBYZERO
(制限の定義によって) 計算の 正確な 結果が無限のとき、0 による除算 (divide-by-zero) 例外は、起こります。例えば、0 で有限の 0 でない数を割るか、または log( 0) を計算すると、0 による除算 (divide-by-zero) 例外を引き起こします。
FE_INEXACT
丸めのために精度の損失があるときはいつも、不正確 (inexact) 例外が起こります。
FE_INVALID
プログラムが、合理的な答えが表せない計算を実行することを試みるとき、無効オペレーション例外は、起こります。例えば、符号付きのような無限大の引き算、0 の 0 除算、NaNss を含む位数比較、と負の数の実際の平方根を取ることは、すべて無効の操作です。
FE_OVERFLOW
0 による除算 (divide-by-zero) と対照的に、正確な結果の大きさが 有限 であるが、目的のタイプに適合するには大きすぎるので、無限大が生成されるとき、オーバフロー例外は、起こります。例えば、 DBL_MAX * 2 を計算することは、オーバフロー例外を引き起こします。
FE_UNDERFLOW
計算の結果が精度を失うとき、0 に近すぎるので、アンダフローは、起こります。結果は、非正規化数または 0 です。

さらに、 FE_ALL_EXCEPT マクロは、上記のフラグと任意のアーキテクチャ特有のフラグのビット毎の論理和 (OR) に展開します。これらのフラグの組み合わせは、それぞれ、プロセッサの浮動小数点の例外フラグをクリアする、格納する、起こす、復元する、と調べるために feclearexcept(), fegetexceptflag(), feraiseexcept(), fesetexceptflag() と fetestexcept() 関数に渡されます。

例外は、 feenableexcept() で アンマスク され、 fedisableexcept() でマスクされます。アンマスクされた例外は、それらが生成されるとき、トラップを引き起こし、すべての例外がデフォルトでマスクされます。現在のマスクは、 fegetexcept() でテストすることができます。

丸めモード

IEEE Std 754-1985 は、4 つの丸めモードを定めています。これらのモードは、2 進の浮動小数点の変数にそれらに適合するためにそれらの正確な値から丸められる結果の方向を制御します。 4 つのモードが次のシンボリック定数に対応しています。
FE_TONEAREST
結果は、表現可能な値に最も近いように丸められます。正確な結果が 2 つの表現可能な値の間のちょうど中間であるなら、最後のバイナリの桁が等しい (ゼロ) 値が選ばれます。これは、デフォルトのモードです。
FE_DOWNWARD
結果は、負の infinity (無限大) に向かって丸められます。
FE_UPWARD
結果は、正の infinity (無限大) に向かって丸められます。
FE_TOWARDZERO
結果は、9 に向かって丸められます。

fegetround() と fesetround() 関数は、丸めモードを問い合わせして、設定します。

環境制御

fegetenv() と fesetenv() 関数は、例外フラグ、現在の例外マスク、丸めモード、とことによると他の実装特有の状態を含んで、浮動小数点の環境を保存して復元します。 feholdexcept() 関数は、 fegetenv() のように振る舞いますが、例外フラグをクリアして、 ノンストップ モードをインストールするという追加の効果があります。ノンストップモードでは、浮動小数点の操作は、いつものように例外フラグを設定しますが、 SIGFPE シグナルが結果として発生しません。ノンストップモードは、デフォルトですが、それは、 feenableexcept() と fedisableexcept() によって変更されるかもしれません。 feupdateenv() 関数は、 fesetenv() と同様に保存された環境を復元しますが、またそれは、古い環境から何らかの浮動小数点の例外も再び起こします。

マクロ FE_DFL_ENV は、デフォルト環境へのポインタに展開します。

使用例

次のルーチンは、平方根関数を計算します。それは、 feraiseexcept() を使用して、適切な入力で明示的に無効例外を起こします。また、それは、中間値を計算している間に不正確例外を延期し、次に、最終的な答えが不正確である場合にだけ、不正確例外が起こされることを許します。

#pragma STDC FENV_ACCESS ON 
double sqrt(double n) { 
 double x = 1.0; 
 fenv_t env; 
 
 if (isnan(n) || n < 0.0) { 
  feraiseexcept(FE_INVALID); 
  return (NAN); 
 } 
 if (isinf(n) || n == 0.0) 
  return (n); 
 feholdexcept(&env); 
 while (fabs((x * x) - n) > DBL_EPSILON * 2 * x) 
  x = (x / 2) + (n / (2 * x)); 
 if (x * x == n) 
  feclearexcept(FE_INEXACT); 
 feupdateenv(&env); 
 return (x); 
}

規格

以下の注意事項を除いて、 < fenv.h> ISO/IEC 9899:1999 (“ISO C99”) に適合しています。 feenableexcept(), fedisableexcept() と fegetexcept() ルーチンは、拡張されています。

歴史

< fenv.h> ヘッダは、 FreeBSD 5.3 ではじめて登場しました。それは、 < ieeefp.h> で定義され、 fpgetround(3) で文書化された標準的でないルーチンにとって代わります。

警告

FENV_ACCESS pragma は
#pragma STDC FENV_ACCESS ON
で有効にでき、
#pragma STDC FENV_ACCESS OFF
指示で無効にすることができます。この語句解析の範囲の注釈は、プログラムが浮動小数点の環境にアクセスするかもしれないとコンパイラに伝えるので、厳しい IEEE-754 セマンティクスに違反する最適化は無効にされます。実行が FENV_ACCESS がオフであるコードのブロックに到達するなら、浮動小数点の環境は未定義になります。

バグ

FENV_ACCESS pragma は、システムコンパイラで実装されていません。しかしながら、一般的に、定数でない式は、低い最適化レベルで正しい副作用を発生させます。
March 16, 2005 FreeBSD