Type-generic math - cppreference.com

##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# Type-generic math

From cppreference.com
< c‎ | numeric

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`

- complex function:

  - float variant `cXXXf`
  - double variant `cXXX`
  - long double variant `cXXXl`

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?

Type-generic macro | Real function variants
--- | ---
| float | double | long double
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`

### [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

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=c/numeric/tgmath&oldid=70934"
Category:

- Todo with reason