C言語/標準ライブラリ/fenv.h

出典: フリー教科書『ウィキブックス(Wikibooks)』

<fenv.h>は、ISO/IEC 9899:1999(通称C99)[1] から導入されたC言語の標準ヘッダーです。<fenv.h>では、浮動小数点環境にアクセスするための 2 つの型といくつかのマクロおよび関数が宣言されています。浮動小数点環境とは、実装でサポートされている浮動小数点ステータス・フラグや浮動小数点制御モードを総称したものです[2]

浮動小数点ステータス・フラグ
浮動小数点数が増えたときにその値がセットされる(そしてクリアされることのない)システム変数のことです。
例外的な浮動小数点演算の副作用として発生する浮動小数点例外が発生したときに、その値がセットされる(クリアされない)システム変数です。
浮動小数点制御モード
浮動小数点演算のその後の動作に影響を与えるために、ユーザが値を設定できるシステム変数です。

[編集]

fenv_t
浮動小数点演算環境全体を表しています。
fexcept_t
fexcept_t型は、浮動小数点ステータス・フラグをまとめて表し、実装がフラグに関連付けるあらゆるステータスを含みます。

マクロ[編集]

各マクロは

FE_DIVBYZERO
FE_INEXACT
FE_INVALID
FE_OVERFLOW
FE_UNDERFLOW
実装が §7.6.2 Floating-point exceptions の関数によって浮動小数点例外をサポートしている場合にのみ定義されます。
実装で定義された追加の浮動小数点例外 FE_ と大文字で始まるマクロ定義を持つ、実装で定義された追加の浮動小数点例外も指定できます。
この様なマクロは実装で指定することができます。定義されたマクロは、整数の定数式に展開されます。
定義されたマクロは、これらのマクロのすべての組み合わせのビットごとの OR により、次のような値を持つ整数の定数式に展開されます。
FE_ALL_EXCEPT
実装で定義されているすべての浮動小数点例外マクロの単純なビット単位のOR。そのようなマクロが定義されていない場合、FE_ALL_EXCEPTは0として定義される。
FE_DOWNWARD
FE_TONEAREST
FE_TOWARDZERO
FE_UPWARD
実装が fegetround および fesetround 関数による表された丸め方向の取得および設定をサポートしている場合にのみ定義されます。FE_ と大文字で始まるマクロ定義を持つ、実装で定義された追加の丸め方向も、実装によって指定することができます。定義されたマクロは、値が非負の値である整数の定数式に展開される。
FE_DFL_ENV
プログラム起動時にインストールされるデフォルトの浮動小数点環境、型は「const-qualified fenv_tへのポインタ」です。これは、浮動小数点環境を管理する <fenv.h> 関数の引数として使用できます。

浮動小数点環境を管理する<fenv.h>関数の引数として使用できます。

FE_と大文字で始まるマクロ定義を持ち、"const-qualified fenv_tへのポインタ "型を持つ、追加の実装定義環境が、実装によって指定されることもあります.

使用例[編集]

#include <fenv.h>
#include <float.h> // for DBL_MAX
#include <stdio.h>

#pragma STDC FENV_ACCESS ON

void show(void) {
  int e = fetestexcept(FE_ALL_EXCEPT);
  if (e & FE_DIVBYZERO)
    puts("FE_DIVBYZERO");
  if (e & FE_INEXACT)
    puts("FE_INEXACT");
  if (e & FE_INVALID)
    puts("FE_INVALID");
  if (e & FE_OVERFLOW)
    puts("FE_OVERFLOW");
  if (e & FE_UNDERFLOW)
    puts("FE_UNDERFLOW");
  if (!e)
    puts("No Floating-point exception");
}

int main(void) {
  feclearexcept(FE_ALL_EXCEPT);
  show();
  double x = 42.0 / 0.0;
  puts(" double x = 42.0 / 0.0");
  show();
  double y = DBL_MAX;
  puts(" double y = DBL_MAX");
  show();
  y += 1;
  puts(" y += 1");
  show();
}
実行結果
% clang12  fe.c -o fe && ./fe
No Floating-point exception
 double x = 42.0 / 0.0
FE_DIVBYZERO
 double y = DBL_MAX
FE_DIVBYZERO
 y += 1
FE_DIVBYZERO
FE_INEXACT
% clang12 -v
clang version 12.0.1
Target: x86_64-portbld-freebsd13.0
Thread model: posix
InstalledDir: /usr/local/llvm12/bin

関数[編集]

<fenv.h>では、浮動小数点環境にアクセスするため以下の関数が宣言されています[3]

<fenv.h>で宣言されている関数
#pragma STDC FENV_ACCESS on-off-switch
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);

浮動小数点例外[編集]

以下の関数は、浮動小数点のステータス・フラグへのアクセスを提供します 219) これらの関数のint入力引数は、浮動小数点例外のサブセットを表しており、ゼロ、または1つ以上の浮動小数点例外マクロのビットごとのORを指定できます(例:FE_OVERFLOW | FE_INEXACTなど)。それ以外の引数値の場合、これらの関数の動作は不定です。

feclearexcept関数[編集]

ISO/IEC 9899:2017 § 7.6.2.1 The feclearexcept function[4]

形式
#include <fenv.h>
int feclearexcept(int excepts);
機能
feclearexcept関数は、引数exceptsで指定されたサポート対象の浮動小数点例外をクリアしようとします。
返却値
feclearexcept関数は、引数exceptsが0の場合、または指定されたすべての例外が正常にクリアされた場合には0を返します。それ以外の場合は、ゼロ以外の値を返します。

fegetexceptflag関数[編集]

ISO/IEC 9899:2017 § 7.6.2.2 The fegetexceptflag function[5]

形式
#include <fenv.h>
int fegetexceptflag(fexcept_t *flagp, int excepts);
機能
fegetexceptflag関数は、引数exceptsで示される浮動小数点のステータスフラグの状態を、実装で定義された表現で、引数flagpで指されるオブジェクトに格納しようとする。
返却値
fegetexceptflag関数は、表現の保存に成功した場合は0を返します。それ以外の場合は、ゼロ以外の値を返します。

feraiseexcept関数[編集]

ISO/IEC 9899:2017 § 7.6.2.3 The feraiseexcept function[6]

形式
#include <fenv.h>
int feraiseexcept(int excepts);
機能
feraiseexcept関数は、引数exceptsで表されるサポートされた浮動小数点例外を発生させようとします[7]。これらの浮動小数点例外を発生させる順序は、F.8.6 Changing the environment に記載されている場合を除き、特定されていません。feraiseexcept 関数が "overflow" または "underflow" 浮動小数点例外を発生させるときに "inexact" 浮動小数点例外を追加で発生させるかどうかは、実装で定義されます。
返却値
feraiseexcept関数は、excepts引数が0の場合、または指定されたすべての例外が正常に発生した場合には0を返します。それ以外の場合は、ゼロ以外の値を返します。

fesetexceptflag関数[編集]

ISO/IEC 9899:2017 § 7.6.2.4 The fesetexceptflag function[8]

形式
#include <fenv.h>
int fesetexceptflag(const fexcept_t *flagp,int excepts);
機能
fesetexceptflag関数は、引数exceptsが示す浮動小数点ステータス・フラグを、flagpが指すオブジェクトに格納されている状態に設定しようとします。flagpの値は、第2引数が少なくともexceptsで示される浮動小数点例外を表すfegetexceptflagの以前の呼び出しによって設定されていなければなりません。この関数は、浮動小数点の例外を発生させず、フラグの状態を設定するだけです。
返却値

fesetexceptflag関数は、引数exceptsがゼロの場合、または指定されたすべてのフラグが適切な状態に正常に設定された場合にはゼロを返します。それ以外の場合は、ゼロ以外の値を返します。

fetestexcept関数[編集]

ISO/IEC 9899:2017 § 7.6.2.5 The fetestexcept function[9]

形式
#include <fenv.h>
int fetestexcept(int excepts);
機能

fetestexcept関数は、浮動小数点例外フラグの指定されたサブセットのうち、どれが現在設定されているかを判定します。引数exceptsは、問い合わせを行う浮動小数点ステータス・フラグを指定します。 この関数によって発生した浮動小数点例外のトラップが取られます。F.8.6の仕様も同じ精神に基づいています。

返却値
fetestexcept関数は、引数exceptsに含まれる現在設定されている浮動小数点例外に対応する浮動小数点例外マクロのビットごとのORの値を返します。

丸め[編集]

fegetround および fesetround 関数は、丸め方向モードの制御を行います。

fegetround関数[編集]

ISO/IEC 9899:2017 § 7.6.3.1 The fegetround function[10]

形式
#include <fenv.h>
int fegetround(void);
機能
fegetround関数は、現在の丸め方向を取得します。
返却値
fegetround関数は、現在の丸め込み方向を表す丸め込み方向マクロの値を返し、そのような丸め込み方向マクロがない場合や現在の丸め込み方向が決定できない場合は負の値を返します。

fesetround関数[編集]

ISO/IEC 9899:2017 § 7.6.3.2 The fesetround function[11]

形式
#include <fenv.h>
int fesetround(int round);
機能
fesetround 関数は、引数 round で表される丸め方向を確立する。引数 round が丸め方向マクロの値と一致しない場合、丸め方向は変更されない。
返却値
fesetround関数は、要求された丸め方向が確立されている場合に限り、ゼロを返します。

環境[編集]

このセクションの関数は、ステータス・フラグやコントロール・モードといった浮動小数点環境を一つの実体として管理します。

fegetenv関数[編集]

ISO/IEC 9899:2017 § 7.6.4.1 The fegetenv function[12]

形式
#include <fenv.h>
int fegetenv(fenv_t *envp);
機能
fegetenv関数は、現在の浮動小数点環境をenvpが指すオブジェクトに格納しようとします。
返却値
fegetenv関数は、環境の保存に成功した場合はゼロを返します。それ以外の場合は、ゼロ以外の値を返します。

feholdexcept関数[編集]

ISO/IEC 9899:2017 § 7.6.4.2 The feholdexcept function[13]

形式
#include <fenv.h>
int feholdexcept(fenv_t *envp);
機能
feholdexcept関数は、引数envpが指すオブジェクトに現在の浮動小数点環境を保存し、浮動小数点のステータス・フラグをクリアした後、利用可能であれば、すべての浮動小数点例外に対してノンストップ(浮動小数点例外時に続行)モードをインストールします。
返却値
feholdexcept関数は、ノンストップ浮動小数点例外処理のインストールに成功した場合にのみ、ゼロを返します。

fesetenv関数[編集]

ISO/IEC 9899:2017 § 7.6.4.3 The fesetenv function[14]

形式
#include <fenv.h>
int fesetenv(const fenv_t *envp);
機能
fesetenv関数は、envpが指すオブジェクトで表される浮動小数点環境を確立しようとするものです。引数envpは、fegetenvまたはfeholdexceptの呼び出しによって設定されたオブジェクトを指すか、または浮動小数点環境マクロに等しくなければならない。

feholdexceptの呼び出しによって設定されたオブジェクトを指すか、または浮動小数点環境マクロに等しい。fesetenvは単にシステムをインストールするだけで、ノンストップモードのみを提供し、その後のインストールは些細なことであることに注意してください。このようなシステムでは、feholdexcept関数をfeupdateenv関数と組み合わせて使用し、呼び出し元から偽の浮動小数点例外を隠すルーチンを書くことができます。 feholdexcept関数は、その引数で表される浮動小数点ステータス・フラグの状態を監視し、これらの浮動小数点例外を発生させません。

返却値
fesetenv関数は、環境の構築に成功した場合は0を返します。それ以外の場合は、ゼロ以外の値を返します。

feupdateenv関数[編集]

ISO/IEC 9899:2017 § 7.6.4.4 The feupdateenv function[15]

形式
#include <fenv.h>
int feupdateenv(const fenv_t *envp);
機能
feupdateenv関数は、現在発生している浮動小数点例外を自動変数に保存し、envpが指すオブジェクトが表す浮動小数点環境をインストールしてから、保存した浮動小数点例外を発生させようとします。引数envpは、feholdexceptまたはfegetenvの呼び出しによって設定されたオブジェクトを指すか、または浮動小数点環境マクロに等しくなければなりません。
返却値
feupdateenv関数は、すべてのアクションが正常に実行された場合はゼロを返します。それ以外の場合は、ゼロ以外の値を返します。
  • N2176 C17 ballot ISO/IEC 9899:2017 Changing the environment[16].

§6.5 Expressions で定義された操作や、標準ライブラリで定義された関数やマクロは、以下のように変更されます。標準ライブラリで定義されている関数やマクロは、それぞれの仕様(IEC 60559への準拠を含む)に従って、浮動小数点のステータスフラグや制御モードを変更する。それ以外の場合は、フラグや制御モードを(ユーザが検知できるように)変更しない。それ以外の場合は、フラグやモードを変更しません。

<fenv.h>のferraiseexcept関数の引数が、IEC 60559で有効なアトミック操作のための一致した浮動小数点例外(すなわち、"overflow "と "inexact"、または "underflow "と "inexact")を表している場合、"overflow "または "underflow "が "inexact "の前に発生します。

double_t x = 1.1e75;

は、表現の評価方法に関わらず、翻訳時に行うことができます。

脚註[編集]

  1. ^ 4年遅れで和訳された JISX3010:2003
  2. ^ C99: ISO/IEC 9899:TC2 Committee Draft — May 6, 2005 WG14/N1124. ISO/IEC. (2005-05-06). p. 187 §7.6 Floating-point environment. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf. 
  3. ^ C11: WG14/N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x. ISO/IEC. p. 420, B.5 Floating-point environment. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf. 
  4. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 152, §7.6.2.1 The feclearexcept function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  5. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 152, §7.6.2.2 The fegetexceptflag function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  6. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 153, §7.6.2.3 The feraiseexcept function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  7. ^ この効果は、算術演算によって発生する浮動小数点例外と同様のものを意図しています。そのため、有効な トラップが取られます。F.8.6 の仕様も同じ精神に基づいています。
  8. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 153, §7.6.2.4 The fesetexceptflag function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  9. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 153, §7.6.2.5 The fetestexcept function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  10. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 154, §7.6.3.1 The fegetround function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  11. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 154, §7.6.3.2 The fesetround function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  12. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 155, §7.6.4.1 The fegetenv function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  13. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 155, §7.6.4.2 The feholdexcept function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  14. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 155, §7.6.4.3 The fesetenv function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  15. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 156, §7.6.4.4 The feupdateenv function. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 
  16. ^ N2176 C17 ballot ISO/IEC 9899:2017. ISO/IEC JTC1/SC22/WG14. p. 374, §F.8.6 Changing the environment. オリジナルの2018-12-30時点によるアーカイブ。. https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf. 

参考文献[編集]