6.21 <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 6-5. Mappings from type-generic macros to <math.h> and <complex.h> functions
Type-generic macro usedCalled function variants with all real argumentsCalled function variants with at least one complex argument
acosacos, acosf, acoslcacos, cacosf, cacosl
asinasin, asinf, asinlcasin, casinf, casinl
atanatan, atanf, atanlcatan, catanf, catanl
acoshacosh, acoshf, acoshlcacosh, cacoshf, cacoshl
asinhasinh, asinhf, asinhlcasinh, casinhf, casinhl
atanhatanh, atanhf, atanhlcatanh, catanhf, catanhl
coscos, cosf, coslccos, ccosf, ccosl
sinsin, sinf, sinlcsin, csinf, csinl
tantan, tanf, tanlctan, ctanf, ctanl
coshcosh, coshf, coshlccosh, ccoshf, ccoshl
sinhsinh, sinhf, sinhlcsinh, csinhf, csinhl
tanhtanh, tanhf, tanhlctanh, ctanhf, ctanhl
expexp, expf, explcexp, cexpf, cexpl
loglog, logf, loglclog, clogf, clogl
powpow, powf, powlcpow, cpowf, cpowl
sqrtsqrt, sqrtf, sqrtlcsqrt, csqrtf, csqrtl
fabsfabs, fabsf, fabslcfabs, cfabsf, cfabsl
atan2atan2, atan2f, atan2lundefined behavior
cbrtcbrt, cbrtf, cbrtlundefined behavior
ceilceil, ceilf, ceillundefined behavior
copysigncopysign, copysignf, copysignlundefined behavior
erferf, erff, erflundefined behavior
erfcerfc, erfcf, erfclundefined behavior
exp2exp2, exp2f, exp2lundefined behavior
expm1expm1, expm1f, expm1lundefined behavior
fdimfdim, fdimf, fdimlundefined behavior
floorfloor, floorf, floorlundefined behavior
fmafma, fmaf, fmalundefined behavior
fmaxfmax, fmaxf, fmaxlundefined behavior
fminfmin, fminf, fminlundefined behavior
fmodfmod, fmodf, fmodlundefined behavior
frexpfrexp, frexpf, frexplundefined behavior
hypothypot, hypotf, hypotlundefined behavior
ilogbilogb, ilogbf, ilogblundefined behavior
ldexpldexp, ldexpf, ldexplundefined behavior
lgammalgamma, lgammaf, lgammalundefined behavior
llrintllrint, llrintf, llrintlundefined behavior
llroundllround, llroundf, llroundlundefined behavior
log10log10, log10f, log10lundefined behavior
log1plog1p, log1pf, log1plundefined behavior
log2log2, log2f, log2lundefined behavior
logblogb, logbf, logblundefined behavior
lrintlrint, lrintf, lrintlundefined behavior
lroundlround, lroundf, lroundlundefined behavior
nearbyintnearbyint, nearbyintf, nearbyintlundefined behavior
nextafternextafter, nextafterf, nextafterlundefined behavior
nexttowardnexttoward, nexttowardf, nexttowardlundefined behavior
remainderremainder, remainderf, remainderlundefined behavior
remquoremquo, remquof, remquolundefined behavior
rintrint, rintf, rintlundefined behavior
roundround, roundf, roundlundefined behavior
scalbnscalbn, scalbnf, scalbnlundefined behavior
scalblnscalbln, scalblnf, scalblnlundefined behavior
tgammatgamma, tgammaf, tgammalundefined behavior
trunctrunc, truncf, trunclundefined behavior
cargcarg, cargf, carglcarg, cargf, cargl
cimagcimag, cimagf, cimaglcimag, cimagf, cimagl
conjconj, conjf, conjlconj, conjf, conjl
cprojcproj, cprojf, cprojlcproj, cprojf, cprojl
crealcreal, crealf, creallcreal, crealf, creall