Type-generic math
From cppreference.com
                    
                                        
                    
                    
                                                            
                    The header <tgmath.h> includes the headers <math.h> and <complex.h> and defines several type-generic macros. These macros determines the actual function to call depending on the types of the parameters.
[edit] Exponential, power, trigonometric and hyperbolic functions (since C99)
A type-generic macro XXX calls either of:
- real function:
-  float variant XXXf
-  double variant XXX
-  long double variant XXXl
 
-  float variant 
- complex function:
-  float variant cXXXf
-  double variant cXXX
-  long double variant cXXXl
 
-  float variant 
An exception to the above rule is exp (see the table below).
The function to call is determined as follows:
- If any of the parameters is complex, then the complex function is called, otherwise the real function is called.
- If any of the parameters is long double, then the long double variant is called. Otherwise, if any of the parameters is double or integer, then the double variant is called. Otherwise, float variant is called.
-  The behavior is undefined if any of the parameters are incompatible with the corresponding argument of the function. This section is incomplete 
 Reason: what's meant by incompatible?
The type-generic macros are as follows:
| Type-generic macro | Real function variants | Complex function variants | ||||
|---|---|---|---|---|---|---|
| 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 | 
[edit] Miscellaneous functions (since C99)
A type-generic macro XXX calls either of the variants of a real function:
-  float variant XXXf
-  double variant XXX
-  long double variant XXXl
Note, there's no modf type-generic macro.
The function to call is determined as follows:
- If any of the parameters is long double, then the long double variant is called. Otherwise, if any of the parameters is double, then the double variant is called. Otherwise, float variant is called.
-  The behavior is undefined is any of the parameters is incompatible with the corresponding argument of the function. This section is incomplete 
 Reason: what's meant by incompatible?
[edit] Example
Run this code
#include <stdio.h> #include <tgmath.h> int main(void) { // macro -> function call int i = 1; printf("cos(1) = %f\n", cos(i) ); // -> cos(i) float f = 0.5; printf("sin(0.5) = %f\n", sin(f) ); // -> sinf(f) long double ld = 1; printf("acos(1) = %Lf\n", acos(ld)); // -> acosl(d) double complex dc = 1 + 0.5*I; double complex result = sqrt(dc); // -> csqrt(dc); printf("sqrt(1 + 0.5i) = %f+%fi\n", creal(result), cimag(result)); }
Output:
cos(1) = 0.540302 sin(0.5) = 0.479426 acos(1) = 0.000000 sqrt(1 + 0.5i) = 1.029086+0.242934i


