型総称数学関数 (C99以降)
ヘッダ <tgmath.h> はヘッダ <math.h> と <complex.h> をインクルードし、引数の型に基づいてどの実数関数、または適用可能な場合はどの複素数関数を呼び出すかを決定する、いくつかの型総称マクロを定義します。
各マクロについて、サフィックスなしの <math.h> 関数で対応する実数型が double である仮引数は、ジェネリックパラメータ(generic parameter)として知られています。(例えば、pow の両方の仮引数はジェネリックパラメータですが、scalbn の最初の仮引数のみがジェネリックパラメータです。)
<tgmath.h> のマクロが使用されるとき、ジェネリックパラメータに渡される引数の型が、以下で説明するようにマクロによってどの関数が選択されるかを決定します。引数の型が選択された関数の仮引数型と互換性がない場合、その振る舞いは未定義です。(例えば、実数専用の <tgmath.h> のマクロに複素数の引数を渡した場合: float complex fc; ceil(fc); や double complex dc; double d; fmax(dc, d); は未定義の振る舞いの例です)。
注:型総称マクロはC99では実装定義の方法で実装されていましたが、C11キーワード _Generic により、これらのマクロを移植可能な方法で実装することが可能になりました。
目次 |
[編集] 複素数/実数 型総称マクロ
実数と複素数の両方の対応部分を持つ全ての関数について、型総称マクロ XXX が存在し、以下のいずれかを呼び出します。
- 実数関数
- float 版
XXXf - double 版
XXX - long double 版
XXXl
- float 版
- 複素数関数
- float 版
cXXXf - double 版
cXXX - long double 版
cXXXl
- float 版
上記の規則の例外は fabs マクロです(以下の表を参照)。
呼び出す関数は次のように決定されます。
- ジェネリックパラメータの引数のいずれかが虚数(imaginary)の場合、その振る舞いは各関数のリファレンスページで個別に指定されます(特に、
sin,cos,tan,cosh,sinh,tanh,asin,atan,asinh, およびatanhは実数関数を呼び出します。sin,tan,sinh,tanh,asin,atan,asinh,atanhの戻り値の型は虚数となり、cosとcoshの戻り値の型は実数となります)。 - ジェネリックパラメータの引数のいずれかが複素数(complex)の場合、複素数関数が呼び出されます。そうでなければ、実数関数が呼び出されます。
- ジェネリックパラメータの引数のいずれかが long double の場合、long double 版が呼び出されます。そうでなく、いずれかの仮引数が double または整数型の場合、double 版が呼び出されます。それ以外の場合は、float 版が呼び出されます。
型総称マクロは以下の通りです。
| 型総称 マクロ |
実数関数の バリエーション |
複素数関数 バリエーション | ||||
|---|---|---|---|---|---|---|
| float | double | long double | 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 を除き、複素数の対応部分を持たない全ての関数について、型総称マクロ XXX が存在し、実数関数のいずれかのバリエーションを呼び出します。
- float 版
XXXf - double 版
XXX - long double 版
XXXl
呼び出す関数は次のように決定されます。
- ジェネリックパラメータの引数のいずれかが long double の場合、long double 版が呼び出されます。そうでなく、ジェネリックパラメータの引数のいずれかが double の場合、double 版が呼び出されます。それ以外の場合は、float 版が呼び出されます。
[編集] 複素数専用関数
実数の対応部分を持たないすべての複素数関数について、型総称マクロ cXXX が存在し、複素数関数のいずれかのバリエーションを呼び出します。
呼び出す関数は次のように決定されます。
- ジェネリックパラメータの引数のいずれかが実数、複素数、または虚数の場合、適切な複素数関数が呼び出されます。
| 型総称 マクロ |
複素数関数 バリエーション | ||
|---|---|---|---|
| float | double | long double | |
| carg | cargf | carg | cargl |
| conj | conjf | conj | conjl |
| creal | crealf | creal | creall |
| cimag | cimagf | cimag | cimagl |
| cproj | cprojf | cproj | cprojl |
[編集] 例
#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
[編集] 参照
- C23標準 (ISO/IEC 9899:2024)
- 7.25 Type-generic math <tgmath.h> (p: TBD)
- C17標準 (ISO/IEC 9899:2018)
- 7.25 型総称数学関数 <tgmath.h> (p: 272-273)
- C11標準 (ISO/IEC 9899:2011)
- 7.25 型総称数学関数 <tgmath.h> (p: 373-375)
- C99標準 (ISO/IEC 9899:1999)
- 7.22 型総称数学関数 <tgmath.h> (p: 335-337)