|
|
本章では、C 言語に新たに追加された、complex.h、fenv.h、inttypes.h、stdbool.h、stdint.h、tgmath.h について説明します。
9.1 complex.h: 複素数
_Complex 型や_Imaginary 型を使いやすくするため、および複素数をサポートする関数のために complex.h が作成されました。今回は、このヘッダで定義されるマクロとプラグマについて説明します。
まずプラグマにはついては、以前紹介した
#pragma STDC CX_LIMITED_RANGE
が complex.h を include することで利用可能になります。
そしてマクロについてです。 complex.h では、complex, imaginary, I というマクロが定義されています。これは _Complex 型や _Imaginary 型を使いやすくするためのものです。具体的に定義例を示すと次のようなものです。
complex.h: マクロ定義例
//complex 型サポート
//他のモジュールで
// const struct { float c[2]; } __cfval01 = {0,1};
//が定義済みとする
#define complex _Complex
#define _Complex_I (*(const float _Complex *)&__cfval01)
//↑0.0+1.0i の値を持つ const float _Complex 型の複素数定数
//imaginary 型サポート
//以下二つは、__STD_IEC_559_COMPLEX__ が定義されているときのみ
#ifdef __STD_IEC_559_COMPLEX__
#define imaginary _Imaginary
#define _Imaginary_I (*(const float _Imaginary *)(__cfval01.c+1))
//↑虚数値 1.0 を持つ虚数型の定数値
#endif
//定数 I サポート
#ifdef _Imaginary_I
#define I _Imaginary_I
#else
#define I _Complex_I
#endif
|
まずはじめに言っておく必要があるのは、__STD_IEC_559_COMPLEX__ が定義されている場合のみ、_Imaginary 型が使用できるので、定義されていない場合 _Imaginary 型とそれに関係するものは使用できないということです。
さて complex.h を include すると _Complex や _Imaginary という表記ではなく、complex、imaginary という表記ができるようマクロ定義されます。したがって、double complex val1 のような便利な表記が使用可能になります。
さらに、I (i の大文字)という記号が定義されます。これは何かというと、複素数で用いられる 1.3+4.5i の i をあらわしています。しかし、i という記号は別の用途で広く利用されているので委員会は、I を当てたようです。では実際どのように用いるのか、どうしてこれを用いると複素数型になるのかを見てみましょう。まず、_Imaginary 型が有効な場合について考えます。例として、1.3+4.5i を考えましょう。これは、C 言語の複素数式で書くと 1.3 + 4.5 * I と書けます。
_Imaginary 型がサポートされている場合
1.3 + 4.5 * I | 通常の計算式同様 * のほうが優先度が高いので 4.5 * I が計算される。I は _Imaginary_I。 |
1.3 + 4.5 * _Imaginary_I | _Imaginary_I を置き換え |
1.3 + 4.5 * ((const float _Imaginary 型の 1.0) | 四則演算のルール、実数型 * _Imaginary 型から結果は _Imaginary 型となる |
1.3 + const double _Imaginary 型の 4.5 | 四則演算のルール、実数型 + _Imaginary 型から結果は _Complex 型 1.3 + 4.5 iとなる |
(const double _Complex)(1.3 + 4.5*I) | 結果として、1.3 + 4.5 * I は左の定数と同じ意味になる |
次に _Imaginary 型がサポートされていない場合を考えてみましょう。委員会は、_Imaginary 型がサポートされていない場合でもそれなりにできるよう、複素数型を設計しました。
_Imaginary 型がサポートされていない場合
1.3 + 4.5 * I | 通常の計算式同様 * のほうが優先度が高いので 4.5 * I が計算される。I は _Complex_I。 |
1.3 + 4.5 * _Complex_I | _Complex_I は const float _Complex 型の定数 0.0+1.0i と同等の値 |
1.3 + 4.5 * const float _Complex 型の 0.0+1.0i の定数値 | 四則演算のルール、実数型 * _Complex 型から結果は _Complex 型となる |
1.3 + const double _Complex 型の定数値 0.0+4.5i | 四則演算のルール、実数型 + _Complex 型から結果は _Complex 型 1.3 + 4.5 iとなる |
(const double _Complex)(1.3 + 4.5*I) | 結果として、1.3 + 4.5 * I は左の定数と同じ意味になる |
このように、C 言語では complex.h を include することでかなり自然な表記で複素数を記述することができるようになっています。またこの定義が気に食わない、支障があるような場合、complex、imaginary、I を再定義したり、未定義にしたりすることが許されています。
さて、次は関数です。complex.h では、複素数を扱った計算が簡単にできるように、多くの関数を用意しています。これらの関数のうち、引数として角度を要求しているものについてはその単位は度ではなくラジアンです。また実装によってはエラーが発生したときに errno に値をセットするものがあります。
#以下間違ってたらごめんね〜
三角関数(trigonometric functions): csin/ccos/ctan
名前 |
csin |
double complex | csin(double complex z); |
float complex | csinf(float complex z); |
long double complex | csinl(long double complex z); |
|
---|
ccos |
double complex | ccos(double complex z); |
float complex | ccosf(float complex z); |
long double complex | ccosl(long double complex z); |
|
ctan |
double complex | ctan(double complex z); |
float complex | ctanf(float complex z); |
long double complex | ctanl(long double complex z); |
|
ヘッダ | complex.h |
引数 | z: csin/ccos/ctan の演算に対する引数
|
戻値 | 演算結果 |
解説 |
z で示される値を関数の引数として、それぞれ sin/cos/tan の演算を行います。
|
逆三角関数(arc trigonometric functions): casin/cacos/catan
名前 |
casin |
double complex | casin(double complex z); |
float complex | casinf(float complex z); |
long double complex | casinl(long double complex z); |
|
---|
cacos |
double complex | cacos(double complex z); |
float complex | cacosf(float complex z); |
long double complex | cacosl(long double complex z); |
|
catan |
double complex | catan(double complex z); |
float complex | catanf(float complex z); |
long double complex | catanl(long double complex z); |
|
ヘッダ | complex.h |
引数 | z: casin/cacos/catan の演算に対する引数
casin/cacos:実数部[-1,1]の外側を枝切り
catan:虚数部[-1,1]の外側を枝切り
|
戻値 | 演算結果
casin/catan:実数部は[-π/2,π/2]の範囲
cacos:実数部は[0,π]の範囲
|
解説 |
z で示される値を関数の引数として、それぞれ arc sine/arc cosine/arc tangent の演算を行います。
|
双曲線関数(hyperbolic functions): csinh/ccosh/ctanh
名前 |
csinh |
double complex | csinh(double complex z); |
float complex | csinhf(float complex z); |
long double complex | csinhl(long double complex z); |
|
---|
ccosh |
double complex | ccosh(double complex z); |
float complex | ccoshf(float complex z); |
long double complex | ccoshl(long double complex z); |
|
ctanh |
double complex | ctanh(double complex z); |
float complex | ctanhf(float complex z); |
long double complex | ctanhl(long double complex z); |
|
ヘッダ | complex.h
|
---|
引数 | z: csinh/ccosh/ctanh の演算に対する引数
|
---|
戻値 | 演算結果
|
---|
解説 |
z で示される値を関数の引数として、それぞれ hyperbolic sine/hyperbolic cosine/hyperbolic tangent の演算を行います。
|
---|
逆双曲線関数(arc hyperbolic functions): casinh/cacosh/catanh
名前 |
casinh |
double complex | casinh(double complex z); |
float complex | casinhf(float complex z); |
long double complex | casinhl(long double complex z); |
|
---|
cacosh |
double complex | cacosh(double complex z); |
float complex | cacoshf(float complex z); |
long double complex | cacoshl(long double complex z); |
|
catanh |
double complex | catanh(double complex z); |
float complex | catanhf(float complex z); |
long double complex | catanhl(long double complex z); |
|
ヘッダ | complex.h |
引数 | z: casinh/cacosh/catanh の演算に対する引数
casinh:虚数部[-1,1]の外側を枝切り
cacosh:実数部 1 未満の値で枝切り
catanh:実数部[-1,1]の外側を枝切り
|
戻値 | 演算結果
casinh/catanh:虚数部は[-π/2,π/2]の範囲
cacosh:実数部は非負で、虚数部は[-π,π]の範囲
|
解説 |
z で示される値を関数の引数として、それぞれ arc hyperbolic sine/arc hyperbolic cosine/arc hyperbolic tangent の演算を行います。
|
指数関数(exponential functions): cexp
名前 |
double complex | cexp(double complex z); |
float complex | cexpf(float complex z); |
long double complex | cexpl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: cexp の演算に対する引数
|
戻値 | 演算結果 |
解説 |
z で示される値を関数の引数として、複素数の基数 e の指数を計算します。
|
自然対数関数(logarithmic functions): clog
名前 |
double complex | clog(double complex z); |
float complex | clogf(float complex z); |
long double complex | clogl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: clog の演算に対する引数(負の実数軸に沿って枝切り)
|
戻値 | e を基数とした log の結果(虚数部は[-π,π]の範囲) |
解説 |
z で示される値を関数の引数として、複素数の自然対数(基数 e) の計算を行います。
|
絶対値関数(absolute-value functions): cabs
名前 |
double | cabs(double complex z); |
float | cabsf(float complex z); |
long double | cabsl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: cabs の演算に対する引数
|
戻値 | 演算結果 |
解説 |
z で示される値を関数の引数として、その絶対値を得ます。
|
平方根関数(square root functions): csqrt
名前 |
double complex | csqrt(double complex z); |
float complex | csqrtf(float complex z); |
long double complex | csqrtl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: csqrt の演算に対する引数(負の実数軸に沿って枝切り)
|
戻値 | 演算結果(実数部/虚数部は非負) |
解説 |
z で示される値を関数の引数として、その平方根を得ます。
|
べき乗関数(power functions): cpow
名前 |
double complex | cpow(double complex x, double complex y); |
float complex | cpowf(float complex x, float complex y); |
long double complex | cpowl(long double complex x, long double complex y); |
|
---|
ヘッダ | complex.h |
引数 | x: 被べき乗数(負の実数軸に沿って枝切り) y: べき乗数
|
戻値 | 演算結果 |
解説 |
xy を計算します。
|
creal/cimag
名前 |
creal |
double | creal(double complex z); |
float | crealf(float complex z); |
long double | creall(long double complex z); |
|
---|
cimag |
double | cimag(double complex z); |
float | cimagf(float complex z); |
long double | cimagl(long double complex z); |
|
ヘッダ | complex.h |
引数 | z: 実数部(creal)/虚数部(cimag)を取り出したい値
|
戻値 | 演算結果 |
解説 |
z で示される値を関数の引数として、それぞれその実数部/虚数部の値を取り出します。creal に関しては (double)z/(float)z/(long double)z と同等と思われます。
|
carg
名前 |
double | carg(double complex z); |
float | cargf(float complex z); |
long double | cargl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: 位相角度を取得したい値(負の実数軸に沿って枝切り)
|
戻値 | 演算結果([-π,π]の範囲) |
解説 |
z で示される値を関数の引数として、その複素平面上の位相角度(phase angle)を取得します。
|
conj
名前 |
double complex | conj(double complex z); |
float complex | conjf(float complex z); |
long double complex | conjl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: 共役複素数を取得したい値
|
戻値 | 演算結果 |
解説 |
z で示される値を関数の引数として、その共役複素数(conjugation)(虚数部の符号が逆)を取得します。
|
cproj
名前 |
double complex | cproj(double complex z); |
float complex | cprojf(float complex z); |
long double complex | cprojl(long double complex z); |
|
---|
ヘッダ | complex.h |
引数 | z: 演算結果を得たい値
|
戻値 | 演算結果 |
解説 |
z で示される値を関数の引数として、リーマン球上での projection を計算します。
|
9.2 fenv.h: 浮動小数点環境
C99 では新たに fenv.h を提供しています。このヘッダは、今まで各環境で扱いがバラバラであった浮動小数点演算における例外と丸め制御を抽象化し扱うためのものです。そのため新たなプラグマ、型、マクロ、関数が定義されています。
まず fenv.h の include で利用可能になるプラグマとしては以前紹介した
#pragma STDC FENV_ACCESS on-off-switch
があります。
まず、型とマクロついて示します。
fenv.h 型
型名 | 解説 |
fenv_t | 浮動小数点環境全体を表す型
|
fexcept_t | 浮動小数点例外フラグ群を表す型。fenv.h で定義される例外フラグの値が入るとは限らない。
|
fenv.h マクロ
マクロ名 | 解説 |
---|
例外フラグ |
FE_DIVBYZERO
FE_INEXACT
FE_INVALID
FE_OVERFLOW
FE_UNDERFLOW
|
fenv.h の中の関数で使用される例外の種類をあらわすマクロ。その例外が実装されているときだけ対応するマクロが定義される。各マクロの値は整数定数(式)に展開される値であり、各値それぞれを bit or できる値。また、FE_UPPERCASESTRING のように、FE_ の後に大文字の文字列が続くマクロは、実装依存の例外をあらわしている。UPPERCASESTRING の部分は、実際は実装依存の例外名に入れ替わる。
|
FE_ALL_EXCEPT |
値 0 に、前記の実装依存の例外フラグを含めた全例外フラグの値を、すべて or した値。
|
丸めフラグ |
FE_UPWARD
FE_DOWNWARD
FE_TOWARDZERO
FE_TONEAREST
|
fegetround/fesetround 関数で使用される値で、それぞれの丸めモードがその環境で実装されているときだけ対応するマクロが定義される。各マクロは正数定数(式)に展開される。FLT_ROUNDS で利用される値と兼用できる。また、FE_UPPERCASESTRING のように、FE_ の後に大文字の文字列が続くマクロは、実装依存の丸めをあらわしている。UPPERCASESTRING の部分は、実際は実装依存の丸め名に入れ替わる。
|
環境 |
FE_DFL_ENV |
型 const fenv_t * を持つ、デフォルト浮動小数点環境。cont fenv_t * の型を持つ名前 FE_xxxx は実装依存の環境名をあらわす。xxxx は対応する環境をあらわす名前である。
|
次に fenv.h で新たに定義された関数について説明します。
例外(exceptions)制御関数
名前 | プロトタイプ | 解説 |
fegetexceptflag |
int | fegetexceptflag(fexcept_t *f, int e); |
|
e で指定された例外フラグを実装定義依存の値として f に格納する。もし格納に成功した場合には 0 を、失敗した場合には、非 0 を返す。
|
fesetexceptflag |
int | fesetexceptflag(const fexcept_t *f, int e); |
|
f で指定されたオブジェクトでの表現に従い、e で指定された例外フラグに対する完全な状態をセットする。e が 0 か状態の設定に成功した場合には 0 を返す。それ以外は非 0を返す。この関数ではフラグの状態をセットするだけで例外は発生しない。
|
feclearexcept |
|
e で指定された例外フラグのクリアを試みる。e が 0 かクリアが成功した場合に 0 を返す。それ以外は非 0 を返す。
|
fetestexcept |
|
e で指定された例外フラグが現在セットされているか検査し、セットされている例外フラグ値を返す。
|
feraiseexcep |
|
e で指定された例外を発生させる。e が 0 か例外の発生に成功した場合は 0 を返す。それ以外は非 0 を返す。overflow または underflow 例外を発生させた後常に inexact 例外を発生させるかどうかは実装依存である。
|
丸め(rounding)制御関数
名前 | プロトタイプ | 解説 |
fegetround |
|
現在の丸モードを丸めフラグの値で返す。
|
fesetround |
|
r で指定された丸めモードにセットする。引数が丸めフラグの値でないときは状態は変更されない。引数で指定された丸め方向に設定できたときに限り 0 を返す。
|
環境(environment)操作関数
名前 | プロトタイプ | 解説 |
fegetenv |
|
現在の浮動小数点環境を e に格納する。成功すると 0 を返す。
|
fesetenv |
int | fesetenv(const fenv_t *e); |
|
現在の浮動小数点環境に指定された浮動小数点環境 e を設定する。設定に成功すると 0 を返す。
|
feholdexcept |
int | feholdexcept(fenv_t *e); |
|
現在の浮動小数点環境を e に格納し、例外フラグをクリアし、可能であれば全例外に対し(例外でも継続する)非停止モードに設定する。もし非停止モードに設定できたときは 0 を返す。
|
feupdateenv |
int | feupdateenv(const fenv_t *e); |
|
現在発生した例外を一時領域に格納し、e で指定された浮動小数点環境を設定した後、一時領域に格納した例外を発生させる。例外発生に成功した場合には 0 を返す。
|
9.3 inttypes.h
stdint.h で定義される整数型、例えば int_fast32_t のような型を使えば、移植性を保ったまま、最も効率のよい整数型を使用することが可能になります。しかし、この型を使った変数を printf で出力したり、scanf で入力することを考えましょう。すると、printf や scanf ではそのような型は定義されていないので指定できません。そのようなことから、利用者は int_fast32_t の実際の型を調べてその型を書式指定名として書かなくてはなりませんが、これでは移植性がなくなってしまいます。
inttypes.h では、書式指定マクロの定義を提供することによりこの問題を解決します。例えば、printf("val=%"PRIxFAST32"\n",intfast32val) の様にして使用します。なお、inttypes.h は自動的に stdint.h を読み込みます。
書式指定マクロ
| 符号 | intN_t | int_leastN_t | int_fastN_t | intmax_t | intptr_t |
fprintf | 符号付き | PRIdN | PRIdLEASTN | PRIdFASTN | PRIdMAX | PRIdPTR |
PRIiN | PRIiLEASTN | PRIiFASTN | PRIiMAX | PRIiPTR |
符号なし | PRIoN | PRIoLEASTN | PRIoFASTN | PRIoMAX | PRIoPTR |
PRIuN | PRIuLEASTN | PRIuFASTN | PRIuMAX | PRIuPTR |
PRIxN | PRIxLEASTN | PRIxFASTN | PRIxMAX | PRIxPTR |
PRIXN | PRIXLEASTN | PRIXFASTN | PRIXMAX | PRIXPTR |
fscanf | 符号付き | SCNdN | SCNdLEASTN | SCNdFASTN | SCNdMAX | SCNdPTR |
SCNiN | SCNiLEASTN | SCNiFASTN | SCNiMAX | SCNiPTR |
符号なし | SCNoN | SCNoLEASTN | SCNoFASTN | SCNoMAX | SCNoPTR |
SCNuN | SCNuLEASTN | SCNuFASTN | SCNuMAX | SCNuPTR |
SCNxN | SCNxLEASTN | SCNxFASTN | SCNxMAX | SCNxPTR |
注:
・N は前に0の付かない符号なし10進数整数をあらわしている。
・C++ では、inttypes.h を include する前に、マクロ __STDC_FORMAT_MACROS を定義した時だけ、これらのマクロが定義される。
|
上で示したマクロ定義に加えて、inttypes.h では、最大幅を持つ整数型を処理するための新しい関数が追加されています。
プロトタイプ |
intmax_t strtoimax(const char *restrict s, char ** restrict endptr, int radix);
uintmax_t strtoumax(const char *restrict s, char ** restrict endptr, int radix);
|
ヘッダ | inttypes.h |
説明 | strtol や strtoul 関数と同様。ただし、intmax_t, uintmax_t を返す点が違う。 |
戻り値 | 変換された結果。変換が失敗した場合は0。オーバーフローした場合には、INTMAX_MAX, INTMAX_MIN, UINTMAX_MAX のどれかが返され、errno に ERANGE がセットされる。 |
プロトタイプ |
intmax_t wcstoimax(const wchar_t *restrict s, wchar_t ** restrict endptr, int radix);
uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t ** restrict endptr, int radix);
|
ヘッダ | inttypes.h |
説明 | wcstol や wcstoul 関数と同様。ただし、intmax_t, uintmax_t を返す点が違う。 |
戻り値 | 変換された結果。変換が失敗した場合は0。オーバーフローした場合には、INTMAX_MAX, INTMAX_MIN, UINTMAX_MAX のどれかが返され、errno に ERANGE がセットされる。 |
9.4 stdbool.h
_Bool 型を便利に簡単にわかりやすく使用できるようにするため、stdbool.h が用意されました。したがって、この型を実際に使用するときには、このヘッダファイルを include することになるでしょう。具体的にはヘッダファイルを見た方が早いと思うので次に示します。
stdbool.h の実装例
/*
* stdbool.h (c)1999 seclan
* ver1.00 1999/06/14 最初のバージョン
*/
#ifndef __bool_true_false_are_defined
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif /* __bool_true_false_are_defined */
|
このように stdbool.h を使用することで、bool, true, false と名前を使用することが可能になります。また __bool_true_false_are_defined が定義されるので既存の環境となるべく衝突しないようプログラムを記述することができます。
ちなみに C++ では _Bool 型は存在しませんが、bool, true, false が存在しており、かつすべて予約語なので、特に何もせずに使用することができます。
9.5 stdint.h
C 言語のプログラムを移植するときの問題点の一つに、typedef された int 型の大きさがあります。例えば、int型 が 32bit と仮定して、int32 という型を typedef して作ったとします。そしてソースプログラム中で int32 という型を使用します。しかし、他の環境へそのソースプログラムを持っていった時には、int が 32bit でないかもしれません。したがって、もしそのままソースプログラムを使用すると 32bit を仮定しているプログラムなのに、実際は 16bit になってしまったということが起こり得ます。そのようなことから環境が変わった場合、新たに定義し直す必要があります。stdint.h はこの問題の一つの解決方法を提示します。
整数を、厳密、最小、演算が速い最小、ポインタ格納可能、最も大きな幅、というクラスにわけ、それをみたす型と限界を定義します。だから、例えば、演算が速い最小の整数型を使えば、他の環境へ持っていってもそのままソースプログラムを再利用することができる可能性が高くなるわけです。
まず型の定義を示します。
以降の定義の注意を示す。型は符号ありと符号なしがセットで提供される。片方だけが提供されることはない。N は前に0の付かない符号なし10進数整数をあらわしている。
厳密な幅を持つ整数型に関する定義
定義名 | 説明 |
intN_t | 符号付き整数型の typedef 名 |
uintN_t | 符号なし整数型の typedef 名 |
厳密にその幅を持つ整数型。これらの型は任意であるが、もし実装が 8, 16, 32, 64 ビットの整数型を提供しているなら相当する typedef 名を定義する必要がある。
例:N=32の場合:int32_t, uint32_t
|
最小の幅を持つ整数型に関する定義
定義名 | 説明 |
int_leastN_t | 少なくとも N bit を持つ符号付き整数型の typedef 名 |
uint_leastN_t | 少なくとも N bit を持つ符号なし整数型の typedef 名 |
その幅を持つ最小の整数型。
int_least8_t, int_least16_t, int_least32_t, int_least64_t,
uint_least8_t, uint_least16_t, uint_least32_t, uint_least64_t
は必須である。その他の型は任意である。
|
最も演算の速い最小の幅を持つ整数型に関する定義
定義名 | 説明 |
int_fastN_t | 少なくとも N bit を持つ最も演算の速い符号付き整数型の typedef 名 |
uint_fastN_t | 少なくとも N bit を持つ最も演算の速い符号なし整数型の typedef 名 |
少なくともその幅を持つ最も演算の速い整数型。これらは、一般的に速いというだけで、すべての目的で最も高速であるということは保証されていない。
int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t,
uint_fast8_t, uint_fast16_t, uint_fast32_t, uint_fast64_t
は必須である。その他の型は任意である。
|
ポインタを格納可能な整数型に関する定義
定義名 | 説明 |
intptr_t | ポインタを格納するのに適切な符号付き整数型の typedef 名 |
uintptr_t | ポインタを格納するのに適切な符号なし整数型の typedef 名 |
void* を (u)intptr_t に変換でき、かつそれを void* に戻せ、その結果が元のポインタと等しくできる整数型。これらの型は任意である。
|
最も大きな幅を持つ整数型に関する定義
定義名 | 説明 |
intmax_t | 符号付き整数型の最も大きな幅を持つ符号付き整数型の typedef 名 |
uintmax_t | 符号なし整数型の最も大きな幅を持つ符号なし整数型の typedef 名 |
これらの型は必須である。
|
次に stdint.h に含まれる、各型の限界の定義について説明します。
以降の定義の注意を示す。C++ では stdint.h を読み込む前に __STDC_LIMIT_MACROS を定義したときだけ以下のマクロが定義される。これらは、#if 式で利用可能である。N は前に0の付かない符号なし10進数整数をあらわしている。
厳密な幅を持つ整数型に関する限界
定義名 | 値 | 説明 |
INTN_MIN | 1-2N-1または-2N-1 | 符号付き整数型の最小値のマクロ名 |
INTN_MAX | 2N-1-1 | 符号付き整数型の最大値のマクロ名 |
UINTN_MAX | 2N-1 | 符号なし整数型の最大値のマクロ名 |
例:N=32の場合
| INT32_MIN | 1-232-1 | = | -2,147,483,647 |
| または | -232-1 | = | -2,147,483,648 |
| INT32_MAX | 232-1-1 | = | 2,147,483,647 |
| UINT32_MAX | 232-1 | = | 4,294,967,295 |
|
最小の幅を持つ整数型に関する限界
定義名 | 保証値 | 説明 |
INT_LEASTN_MIN | 1-2N-1 | 符号付き整数型の最小値のマクロ名 |
INT_LEASTN_MAX | 2N-1-1 | 符号付き整数型の最大値のマクロ名 |
UINT_LEASTN_MAX | 2N-1 | 符号なし整数型の最大値のマクロ名 |
最も演算の速い最小の幅を持つ整数型に関する限界
定義名 | 保証値 | 説明 |
INT_FASTN_MIN | 1-2N-1 | 符号付き整数型の最小値のマクロ名 |
INT_FASTN_MAX | 2N-1-1 | 符号付き整数型の最大値のマクロ名 |
UINT_FASTN_MAX | 2N-1 | 符号なし整数型の最大値のマクロ名 |
ポインタを格納可能な整数型に関する限界
定義名 | 保証値 | 説明 |
INTPTR_MIN | -32767 | 符号付き整数型の最小値のマクロ名 |
INTPTR_MAX | 32767 | 符号付き整数型の最大値のマクロ名 |
UINTPTR_MAX | 65535 | 符号なし整数型の最大値のマクロ名 |
最も大きな幅を持つ整数型に関する限界
定義名 | 保証値 | 説明 |
INTMAX_MIN | 1-263 | 符号付き整数型の最小値のマクロ名 |
INTMAX_MAX | 263-1 | 符号付き整数型の最大値のマクロ名 |
UINTMAX_MAX | 264-1 | 符号なし整数型の最大値のマクロ名 |
その他の整数型に関する限界
定義名 | 保証値 | 説明 |
PTRDIFF_MIN | -65535 | ptrdiff_t の下限のマクロ名 |
PTRDIFF_MAX | 65535 | ptrdiff_t の上限のマクロ名 |
SIG_ATOMIC_MIN | -127 | sig_atomic_t が符号あり整数で定義されたときの下限のマクロ名 |
0 | sig_atomic_t が符号なし整数で定義されたときの下限のマクロ名 |
SIG_ATOMIC_MAX | 127 | sig_atomic_t が符号あり整数で定義されたときの上限のマクロ名 |
255 | sig_atomic_t が符号なし整数で定義されたときの上限のマクロ名 |
WCHAR_MIN | -127 | wchar_t が符号あり整数で定義されたときの下限のマクロ名 |
0 | wchar_t が符号なし整数で定義されたときの下限のマクロ名 |
WCHAR_MAX | 127 | wchar_t が符号あり整数で定義されたときの上限のマクロ名 |
255 | wchar_t が符号なし整数で定義されたときの上限のマクロ名 |
WINT_MIN | -32767 | wint_t が符号あり整数で定義されたときの下限のマクロ名 |
0 | wint_t が符号なし整数で定義されたときの下限のマクロ名 |
WINT_MAX | 32767 | wint_t が符号あり整数で定義されたときの上限のマクロ名 |
65535 | wint_t が符号なし整数で定義されたときの上限のマクロ名 |
SIZE_MAX | 65535 | size_t の上限のマクロ名 |
整数定数用マクロ
定義名 | 説明 |
INTN_C(値) | 値を int_leastN_t を型とする符号付き整数定数式へ展開するマクロ |
UINTN_C(値) | 値を uint_leastN_t を型とする符号なし整数定数式へ展開するマクロ |
INTMAX_C(値) | 値を intmax_t を型とする符号付き整数定数式へ展開するマクロ |
UINTMAX_C(値) | 値を uintmax_t を型とする符号なし整数定数式へ展開するマクロ |
9.6 tgmath.h: 型総称数学関数
今まで見てきたように、今回の C 言語では complex 型がサポートされ、また数学関係の関数が大量に追加、強化されています。しかし、実際の使用では面倒なことが起こることがあります。例えば、sin 関数を使うことを考えると、float 型の引数に対しては sinf を、double 型の変数に対しては sin を使用する必要があります。しかし後から精度が足りなくなってそれらの型を long double 型に変更した場合には、すべての関数名を sinl に変更しなくてはなりません。これは面倒です。またいちいち実数型、複素数型の関数名を覚えるのは面倒です。sin って書いたら適当に判別してくれたらいいのに! tgmath.h はまさにその機能を提供します。
tgmath.h を include すると、引数型に応じ自動的に適切な名前に関数名が展開されます。例えば、sin 関数の引数に double 型または int 型を書くと sin 関数に、long double 型を書くと sinl 関数に、float 型を書くと sinf に、float complex 型を書くと csinf に、long double complex 型を書くと csinl にといった具合です。
実際の展開方法は次のように行います。まず、引数が complex 型である場合、対応する complex.h の中にある複素数関数に展開されます。もし引数に long double 型があるなら math.h の中の対応する実数関数 xxxxl に展開されます。もし引数に double 型または int 型のような整数型があるなら実数関数 xxxx に展開されます。さもなくば、float 型の指定とみなし xxxxf に展開します。また展開の結果対応する関数が存在していないような場合、その動作は未定義となります。
なお、tgmath.h は自動的に math.h と complex.h を include します。
最後に、tgmath.h で定義される関数名とその展開後の名前の一覧を示します。
tgmath.h で定義されるマクロとその展開先関数名一覧
tgmath.h | math.h | complex.h |
generic | double | float | long double | double complex | float complex | long double complex |
sin | sin | sinf | sinl | csin | csinf | csinl |
cos | cos | cosf | cosl | ccos | ccosf | ccosl |
tan | tan | tanf | tanl | ctan | ctanf | ctanl |
asin | asin | asinf | asinl | casin | casinf | casinl |
acos | acos | acosf | acosl | cacos | cacosf | cacosl |
atan | atan | atanf | atanl | catan | catanf | catanl |
sinh | sinh | sinhf | sinhl | csinh | csinhf | csinhl |
cosh | cosh | coshf | coshl | ccosh | ccoshf | ccoshl |
tanh | tanh | tanhf | tanhl | ctanh | ctanhf | ctanhl |
asinh | asinh | asinhf | asinhl | casinh | casinhf | casinhl |
acosh | acosh | acoshf | acoshl | cacosh | cacoshf | cacoshl |
atanh | atanh | atanhf | atanhl | catanh | catanhf | catanhl |
exp | exp | expf | expl | cexp | cexpf | cexpl |
log | log | logf | logl | clog | clogf | clogl |
pow | pow | powf | powl | cpow | cpowf | cpowl |
sqrt | sqrt | sqrtf | sqrtl | csqrt | csqrtf | csqrtl |
fabs | fabs | fabsf | fabsl | cabs | cabsf | cabsl |
atan2 | atan2 | atan2f | atan2l | N/A |
cbrt | cbrt | cbrtf | cbrtl | N/A |
ceil | ceil | ceilf | ceill | N/A |
copysign | copysign | copysignf | copysignl | N/A |
erf | erf | erff | erfl | N/A |
erfc | erfc | erfcf | erfcl | N/A |
exp2 | exp2 | exp2f | exp2l | N/A |
expm1 | expm1 | expm1f | expm1l | N/A |
fdim | fdim | fdimf | fdiml | N/A |
floor | floor | floorf | floorl | N/A |
fma | fma | fmaf | fmal | N/A |
fmax | fmax | fmaxf | fmaxl | N/A |
fmin | fmin | fminf | fminl | N/A |
fmod | fmod | fmodf | fmodl | N/A |
frexp | frexp | frexpf | frexpl | N/A |
hypot | hypot | hypotf | hypotl | N/A |
ilogb | ilogb | ilogbf | ilogbl | N/A |
ldexp | ldexp | ldexpf | ldexpl | N/A |
lgamma | lgamma | lgammaf | lgammal | N/A |
llrint | llrint | llrintf | llrintl | N/A |
llround | llround | llroundf | llroundl | N/A |
log10 | log10 | log10f | log10l | N/A |
log1p | log1p | log1pf | log1pl | N/A |
log2 | log2 | log2f | log2l | N/A |
logb | logb | logbf | logbl | N/A |
lrint | lrint | lrintf | lrintl | N/A |
lround | lround | lroundf | lroundl | N/A |
nearbyint | nearbyint | nearbyintf | nearbyintl | N/A |
nextafter | nextafter | nextafterf | nextafterl | N/A |
nexttoward | nexttoward | nexttowardf | nexttowardl | N/A |
remainder | remainder | remainderf | remainderl | N/A |
remquo | remquo | remquof | remquol | N/A |
rint | rint | rintf | rintl | N/A |
round | round | roundf | roundl | N/A |
scalbn | scalbn | scalbnf | scalbnl | N/A |
scalbln | scalbln | scalblnf | scalblnl | N/A |
tgamma | tgamma | tgammaf | tgammal | N/A |
trunc | trunc | truncf | truncl | N/A |
creal | N/A | creal | crealf | creall |
cimag | N/A | cimag | cimagf | cimagl |
carg | N/A | carg | cargf | cargl |
conj | N/A | conj | conjf | conjl |
cproj | N/A | cproj | cprojf | cprojl |
注意:
N/A には対応する関数が存在しない。指定すると未定義の動作を意味する。
[■]色以外のすべての関数は、今回の C の規格で追加された関数。
|
|
|
|