Common mathematical functions | ||||
Floating-point environment(C99) | ||||
Pseudo-random number generation | ||||
Complex number arithmetic(C99) | ||||
Type-generic math(C99) | ||||
Bit manipulation(C23) | ||||
Checked integer arithmetic(C23) |
The header<tgmath.h> includes the headers<math.h> and<complex.h> and defines severaltype-generic macros that determine which real or, when applicable, complex function to call based on the types of the arguments.
For each macro, the parameters whose corresponding real type in the unsuffixed<math.h> function isdouble are known asgeneric parameters (for example, both parameters ofpow are generic parameters, but only the first parameter ofscalbn is a generic parameter).
When a<tgmath.h>'s macro is used the types of the arguments passed to the generic parameters determine which function is selected by the macro as described below. If the types of the arguments are notcompatible with the parameter types of the selected function, the behavior is undefined (e.g. if a complex argument is passed into a real-only<tgmath.h>'s macro:floatcomplex fc;ceil(fc); ordoublecomplex dc;double d;fmax(dc, d); are examples of undefined behavior).
Note: type-generic macros were implemented in implementation-defined manner in C99, but C11 keyword_Generic makes it possible to implement these macros in portable manner.
Contents |
For all functions that have both real and complex counterparts, a type-generic macroXXX
exists, which calls either of:
XXXf
XXX
XXXl
cXXXf
cXXX
cXXXl
An exception to the above rule is thefabs
macro (see the table below).
The function to call is determined as follows:
sin
,cos
,tan
,cosh
,sinh
,tanh
,asin
,atan
,asinh
, andatanh
callreal functions, the return types ofsin
,tan
,sinh
,tanh
,asin
,atan
,asinh
, andatanh
are imaginary, and the return types ofcos
andcosh
are real).The type-generic macros are as follows:
Type-generic macro | Real function variants | Complex function variants | ||||
---|---|---|---|---|---|---|
float | double | longdouble | float | double | longdouble | |
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 |
For all functions that do not have complex counterparts, with the exception ofmodf
, a type-generic macroXXX
exists, which calls either of the variants of a real function:
XXXf
XXX
XXXl
The function to call is determined as follows:
Type-generic macro | Real function variants | ||
---|---|---|---|
float | double | longdouble | |
atan2 | atan2f | atan2 | atan2l |
cbrt | cbrtf | cbrt | cbrtl |
ceil | ceilf | ceil | ceill |
copysign | copysignf | copysign | copysignl |
erf | erff | erf | erfl |
erfc | erfcf | erfc | erfcl |
exp2 | exp2f | exp2 | exp2l |
expm1 | expm1f | expm1 | expm1l |
fdim | fdimf | fdim | fdiml |
floor | floorf | floor | floorl |
fma | fmaf | fma | fmal |
fmax | fmaxf | fmax | fmaxl |
fmin | fminf | fmin | fminl |
fmod | fmodf | fmod | fmodl |
frexp | frexpf | frexp | frexpl |
hypot | hypotf | hypot | hypotl |
ilogb | ilogbf | ilogb | ilogbl |
ldexp | ldexpf | ldexp | ldexpl |
lgamma | lgammaf | lgamma | lgammal |
llrint | llrintf | llrint | llrintl |
llround | llroundf | llround | llroundl |
log10 | log10f | log10 | log10l |
log1p | log1pf | log1p | log1pl |
log2 | log2f | log2 | log2l |
logb | logbf | logb | logbl |
lrint | lrintf | lrint | lrintl |
lround | lroundf | lround | lroundl |
nearbyint | nearbyintf | nearbyint | nearbyintl |
nextafter | nextafterf | nextafter | nextafterl |
nexttoward | nexttowardf | nexttoward | nexttowardl |
remainder | remainderf | remainder | remainderl |
remquo | remquof | remquo | remquol |
rint | rintf | rint | rintl |
round | roundf | round | roundl |
scalbln | scalblnf | scalbln | scalblnl |
scalbn | scalbnf | scalbn | scalbnl |
tgamma | tgammaf | tgamma | tgammal |
trunc | truncf | trunc | truncl |
For all complex number functions that do not have real counterparts, a type-generic macrocXXX
exists, which calls either of the variants of a complex function:
The function to call is determined as follows:
Type-generic macro | Complex function variants | ||
---|---|---|---|
float | double | longdouble | |
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 floatcomplex dc=1+0.5*I;floatcomplex z=sqrt(dc);// argument type is float complex, calls csqrtfprintf("sqrt(1 + 0.5i) = %f+%fi\n",creal(z),// argument type is float complex, calls crealfcimag(z));// argument type is float complex, calls cimagf}
Output:
sqrt(2) = 1.414214sin(0.5f) = 0.479426sqrt(1 + 0.5i) = 1.029086+0.242934i