<tgmath.h> Type-generic Math

Attention: This header is not implemented when building with MPLAB XC8 for PIC MCUs.

The header file tgmath.h provides mappings from a generic math macro to either a real or complex math function, defined by <math.h> or <complex.h>. They allows a specific variant of some math functions to be called, based on the type of the arguments passed to the macro. The <math.h> and <complex.h> headers are included by <tgmath.h>.

Real functions in <math.h> come in three variants: an unsuffixed function, and a float and a long double variant, indicated by an f and l suffix in the function name, for example, sin(), sinf(), and sinl(). Complex functions in <complex.h> all use a c prefix and again come in an unsuffixed variant and a float complex and a long double complex variant, indicated by an f and l suffix in the function name, for example cexp(), cexpf(), and cexpl().

For all of these real and complex functions, except for the modf() function, a type-generic macro is defined by <tgmath.h>. When a type-generic macro is used, the following rules determine the called function.

If there are only c-prefixed complex function variants of the macro, then one of those function variants is called, regardless of the type of the argument. Where there are real variants of the function, the following rules apply.

If any argument has long double complex type and the c-prefixed complex variant of the function exists, the function using a c prefix and l suffix will be called. If the c-prefixed variant of the function does not exist, the behavior is undefined. Otherwise, if any argument has long double type, the function uses an l suffix will be called. For example using the acos() type-generic macro with a long double argument will call the acosl() function; using the acos() type-generic macro with a long double complex argument will call the cacosl() function.

If any argument has double complex type and the c-prefixed complex variant of the function exists, the function using a c prefix and no suffix will be called. If the c-prefixed variant of the function does not exist, the behavior is undefined. Otherwise, if any argument has double or integer type, the function with no suffix will be called. For example using the acos() type-generic macro with a int argument will call the acos() function; using the acos() type-generic macro with a double complex argument will call the cacos() function.

If any argument has float complex type and the c-prefixed complex variant of the function exists, the function using a c prefix and f suffix will be called. If the c-prefixed variant of the function does not exist, the behavior is undefined. Otherwise, if any argument has float type, the function uses an f suffix will be called. For example using the acos() type-generic macro with a float argument will call the acosf() function; using the acos() type-generic macro with a float complex argument will call the cacosf() function.

The application of these rules for all type-generic macros are indicated in the table below.

Table 1. Mappings from type-generic macros to <math.h> and <complex.h> functions
Type-generic macro used Called function variants with all real arguments Called function variants with at least one complex argument
acos acos, acosf, acosl cacos, cacosf, cacosl
asin asin, asinf, asinl casin, casinf, casinl
atan atan, atanf, atanl catan, catanf, catanl
acosh acosh, acoshf, acoshl cacosh, cacoshf, cacoshl
asinh asinh, asinhf, asinhl casinh, casinhf, casinhl
atanh atanh, atanhf, atanhl catanh, catanhf, catanhl
cos cos, cosf, cosl ccos, ccosf, ccosl
sin sin, sinf, sinl csin, csinf, csinl
tan tan, tanf, tanl ctan, ctanf, ctanl
cosh cosh, coshf, coshl ccosh, ccoshf, ccoshl
sinh sinh, sinhf, sinhl csinh, csinhf, csinhl
tanh tanh, tanhf, tanhl ctanh, ctanhf, ctanhl
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 cfabs, cfabsf, cfabsl
atan2 atan2, atan2f, atan2l undefined behavior
cbrt cbrt, cbrtf, cbrtl undefined behavior
ceil ceil, ceilf, ceill undefined behavior
copysign copysign, copysignf, copysignl undefined behavior
erf erf, erff, erfl undefined behavior
erfc erfc, erfcf, erfcl undefined behavior
exp2 exp2, exp2f, exp2l undefined behavior
expm1 expm1, expm1f, expm1l undefined behavior
fdim fdim, fdimf, fdiml undefined behavior
floor floor, floorf, floorl undefined behavior
fma fma, fmaf, fmal undefined behavior
fmax fmax, fmaxf, fmaxl undefined behavior
fmin fmin, fminf, fminl undefined behavior
fmod fmod, fmodf, fmodl undefined behavior
frexp frexp, frexpf, frexpl undefined behavior
hypot hypot, hypotf, hypotl undefined behavior
ilogb ilogb, ilogbf, ilogbl undefined behavior
ldexp ldexp, ldexpf, ldexpl undefined behavior
lgamma lgamma, lgammaf, lgammal undefined behavior
llrint llrint, llrintf, llrintl undefined behavior
llround llround, llroundf, llroundl undefined behavior
log10 log10, log10f, log10l undefined behavior
log1p log1p, log1pf, log1pl undefined behavior
log2 log2, log2f, log2l undefined behavior
logb logb, logbf, logbl undefined behavior
lrint lrint, lrintf, lrintl undefined behavior
lround lround, lroundf, lroundl undefined behavior
nearbyint nearbyint, nearbyintf, nearbyintl undefined behavior
nextafter nextafter, nextafterf, nextafterl undefined behavior
nexttoward nexttoward, nexttowardf, nexttowardl undefined behavior
remainder remainder, remainderf, remainderl undefined behavior
remquo remquo, remquof, remquol undefined behavior
rint rint, rintf, rintl undefined behavior
round round, roundf, roundl undefined behavior
scalbn scalbn, scalbnf, scalbnl undefined behavior
scalbln scalbln, scalblnf, scalblnl undefined behavior
tgamma tgamma, tgammaf, tgammal undefined behavior
trunc trunc, truncf, truncl undefined behavior
carg carg, cargf, cargl carg, cargf, cargl
cimag cimag, cimagf, cimagl cimag, cimagf, cimagl
conj conj, conjf, conjl conj, conjf, conjl
cproj cproj, cprojf, cprojl cproj, cprojf, cprojl
creal creal, crealf, creall creal, crealf, creall