型総称数学
提供: cppreference.com
ヘッダ <tgmath.h>
は、 <math.h>
および <complex.h>
をインクルードし、引数の型に応じて呼ぶ関数を決定する型総称マクロをいくつか定義します。
各マクロにおいて、対応する <math.h> の数学関数では double であるところの引数は、総称引数と呼ばれます (例えば pow では両方の引数が総称引数ですが、 scalbn では最初の引数のみが総称引数です)。
<tgmath.h>
のマクロを使用する場合、総称引数に渡した実引数の型に応じて後述するように関数が選択されます。 実引数の型が選択された関数の仮引数の型と互換でない場合、動作は未定義です (実数のみの型総称マクロに複素数を渡した場合など)。 float complex fc; ceil(fc) や double complex dc; double d; fmax(dc, d) は未定義動作の例です。
ノート: 型総称マクロは C99 では処理系定義の方法で実装されていましたが、 C11 ではキーワード _Generic によって移植性のある方法で実装できます。
目次 |
[編集] 複素数および実数の型総称マクロ
実数版と複素数版の両方があるすべての関数に対して型総称マクロが存在し、以下のいずれかを呼びます。
- float 版の関数
~f
- double 版の関数
~
- long double 版の関数
~l
- float complex 版の関数
c~f
- double complex 版の関数
c~
- long double complex 版の関数
c~l
fabs
マクロは上記ルールの例外です (下の表を参照してください)。
呼ぶ関数は以下のように決定されます。
- 総称引数のいずれかが虚数であれば、その動作は各関数のリファレンスページで個別に規定されます (特に sin, cos, tan, cosh, sinh, tanh, asin, atan, asinh, atanh は実数版の関数を呼びますが、 sin, tan, sinh, tanh, asin, atan, asinh, atan の戻り値は虚数になり、 cos, cosh の戻り値は実数になります)
- 総称引数のいずれかが複素数であれば複素数版の関数が呼ばれ、そうでなければ実数版の関数が呼ばれます
- 総称引数のいずれかが long double であれば long double 版が呼ばれ、そうでなくて総称引数のいずれかが double または整数であれば double 版が呼ばれ、そうでなければ float 版が呼ばれます。
型総称マクロは以下の通りです。
型総称マクロ | 実数版の関数 | 複素数版の関数 | ||||
---|---|---|---|---|---|---|
float |
double |
long double |
|
|
| |
fabs | fabsf | fabs | fabsl | cabsf | cabs | cabsl |
exp | expf | exp | expl | cexpf | cexp | cexpl |
log | logf | log | logl | clogf | clog | clogl |
pow | powf | pow | powl | cpowf | cpow | cpowl |
sqrt | sqrtf | sqrt | sqrtl | csqrtf | csqrt | csqrtl |
sin | sinf | sin | sinl | csinf | csin | csinl |
cos | cosf | cos | cosl | ccosf | ccos | ccosl |
tan | tanf | tan | tanl | ctanf | ctan | ctanl |
asin | asinf | asin | asinl | casinf | casin | casinl |
acos | acosf | acos | acosl | cacosf | cacos | cacosl |
atan | atanf | atan | atanl | catanf | catan | catanl |
sinh | sinhf | sinh | sinhl | csinhf | csinh | csinhl |
cosh | coshf | cosh | coshl | ccoshf | ccosh | ccoshl |
tanh | tanhf | tanh | tanhl | ctanhf | ctanh | ctanhl |
asinh | asinhf | asinh | asinhl | casinhf | casinh | casinhl |
acosh | acoshf | acosh | acoshl | cacoshf | cacosh | cacoshl |
atanh | atanhf | atanh | atanhl | catanhf | catanh | catanhl |
[編集] 実数のみの関数
複素数版がないすべての関数 (modf
を除く) に対して型総称マクロが存在し、以下のいずれかを呼びます。
- float 版の関数
~f
- double 版の関数
~
- long double 版の関数
~l
呼ぶ関数は以下のように決定されます。
- 総称引数のいずれかが long double であれば long double 版が呼ばれ、そうでなくて総称引数のいずれかが double であれば double 版が呼ばれ、そうでなければ float 版が呼ばれます。
[編集] 複素数のみの関数
実数版のないすべての複素数関数に対して型総称マクロが存在し、以下のいずれかを呼びます。
呼ぶ関数は以下のように決定されます。
- 総称引数のいずれかが実数、複素数または虚数の場合、適切な複素数関数が呼ばれます。
型総称マクロ | 複素数版の関数 | ||
---|---|---|---|
|
|
| |
carg | cargf | carg | cargl |
conj | conjf | conj | conjl |
creal | crealf | creal | creall |
cimag | cimagf | cimag | cimagl |
cproj | cprojf | cproj | cprojl |
[編集] 例
Run this code
#include <stdio.h> #include <tgmath.h> int main(void) { int i = 2; printf("sqrt(2) = %f\n", sqrt(i)); // argument type is int, calls sqrt float f = 0.5; printf("sin(0.5f) = %f\n", sin(f)); // argument type is float, calls sinf float complex dc = 1 + 0.5*I; float complex z = sqrt(dc); // argument type is float complex, calls csqrtf printf("sqrt(1 + 0.5i) = %f+%fi\n", creal(z), // argument type is float complex, calls crealf cimag(z)); // argument type is float complex, calls cimagf }
出力:
sqrt(2) = 1.414214 sin(0.5f) = 0.479426 sqrt(1 + 0.5i) = 1.029086+0.242934i
[編集] 参考文献
- C11 standard (ISO/IEC 9899:2011):
- 7.25 Type-generic math <tgmath.h> (p: 373-375)
- C99 standard (ISO/IEC 9899:1999):
- 7.22 Type-generic math <tgmath.h> (p: 335-337)