# C Programming/Further math

The `<math.h>` header contains prototypes for several functions that
deal with mathematics. In the 1990 version of the ISO standard, only the
`double` versions of the functions were specified; the 1999 version
added the `float` and `long double` versions. To use these math
functions, you must link your program with the math library. For some
compilers (including GCC), you must specify the additional parameter
`-lm`[^1][^2].

The math functions may produce one of two kinds of errors. *Domain
errors* occur when the parameters to the functions are invalid, such as
a negative number as a parameter to `sqrt` (the square root function).
*Range errors* occur when the result of the function cannot be expressed
in that particular floating-point type, such as `pow(1000.0, 1000.0)` if
the maximum value of a double is around 10^308^.

The functions can be grouped into the following categories:

## Trigonometric functions

### The `acos` and `asin` functions

The `acos` functions return the arccosine of their arguments in radians,
and the `asin` functions return the arcsine of their arguments in
radians. All functions expect the argument in the range \[-1,+1\]. The
arccosine returns a value in the range \[0,π\]; the arcsine returns a
value in the range \[-π/2,+π/2\].

``` c
 #include <math.h>
 float asinf(float x); /* C99 */
 float acosf(float x); /* C99 */
 double asin(double x);
 double acos(double x);
 long double asinl(long double x); /* C99 */
 long double acosl(long double x); /* C99 */
```

### The `atan` and `atan2` functions

The `atan` functions return the arctangent of their arguments in
radians, and the `atan2` function return the arctangent of `y/x` in
radians. The `atan` functions return a value in the range \[-π/2,+π/2\]
(the reason why ±π/2 are included in the range is because the
floating-point value may represent infinity, and atan(±∞) = ±π/2); the
`atan2` functions return a value in the range \[-π,+π\]. For `atan2`, a
domain error may occur if both arguments are zero.

``` c
 #include <math.h>
 float atanf(float x); /* C99 */
 float atan2f(float y, float x); /* C99 */
 double atan(double x);
 double atan2(double y, double x);
 long double atanl(long double x); /* C99 */
 long double atan2l(long double y, long double x); /* C99 */
```

### The `cos`, `sin`, and `tan` functions

The `cos`, `sin`, and `tan` functions return the cosine, sine, and
tangent of the argument, expressed in radians.

``` c
 #include <math.h>
 float cosf(float x); /* C99 */
 float sinf(float x); /* C99 */
 float tanf(float x); /* C99 */
 double cos(double x);
 double sin(double x);
 double tan(double x);
 long double cosl(long double x); /* C99 */
 long double sinl(long double x); /* C99 */
 long double tanl(long double x); /* C99 */
```

## Hyperbolic functions

The `cosh`, `sinh` and `tanh` functions compute the hyperbolic cosine,
the hyperbolic sine, and the hyperbolic tangent of the argument
respectively. For the hyperbolic sine and cosine functions, a range
error occurs if the magnitude of the argument is too large.

The `acosh` functions compute the inverse hyperbolic cosine of the
argument. A domain error occurs for arguments less than 1.

The `asinh` functions compute the inverse hyperbolic sine of the
argument.

The `atanh` functions compute the inverse hyperbolic tangent of the
argument. A domain error occurs if the argument is not in the interval
\[-1, +1\]. A range error may occur if the argument equals -1 or +1.

``` c
 #include <math.h>
 float coshf(float x); /* C99 */
 float sinhf(float x); /* C99 */
 float tanhf(float x); /* C99 */
 double cosh(double x); 
 double sinh(double x);
 double tanh(double x);
 long double coshl(long double x); /* C99 */
 long double sinhl(long double x); /* C99 */
 long double tanhl(long double x); /* C99 */
 float acoshf(float x); /* C99 */
 float asinhf(float x); /* C99 */
 float atanhf(float x); /* C99 */
 double acosh(double x); /* C99 */
 double asinh(double x); /* C99 */
 double atanh(double x); /* C99 */
 long double acoshl(long double x); /* C99 */
 long double asinhl(long double x); /* C99 */
 long double atanhl(long double x); /* C99 */
```

## Exponential and logarithmic functions

### The `exp`, `exp2`, and `expm1` functions

The `exp` functions compute the base-*e* exponential function of `x`
(*e*^x^). A range error occurs if the magnitude of `x` is too large.

The `exp2` functions compute the base-2 exponential function of `x`
(2^x^). A range error occurs if the magnitude of `x` is too large.

The `expm1` functions compute the base-*e* exponential function of the
argument, minus 1. A range error occurs if the magnitude of `x` is too
large.

``` c
 #include <math.h>
 float expf(float x); /* C99 */
 double exp(double x);
 long double expl(long double x); /* C99 */
 float exp2f(float x); /* C99 */
 double exp2(double x); /* C99 */
 long double exp2l(long double x); /* C99 */
 float expm1f(float x); /* C99 */
 double expm1(double x); /* C99 */
 long double expm1l(long double x); /* C99 */
```

### The `frexp`, `ldexp`, `modf`, `scalbn`, and `scalbln` functions

These functions are heavily used in software floating-point emulators,
but are otherwise rarely directly called.

Inside the computer, each floating point number is represented by two
parts:

-   The significand is either in the range \1/2, 1), or it equals zero.
-   The exponent is an integer.

The value of a floating point number $v$ is
$v = {\rm significand} \times 2^{\rm exponent}$.

The `frexp` functions break the argument floating point number `value`
into those two parts, the exponent and significand. After breaking it
apart, it stores the exponent in the `int` object pointed to by `ex`,
and returns the significand. In other words, the value returned is a
copy of the given floating point number but with an exponent replaced by
0. If `value` is zero, both parts of the result are zero.

The `ldexp` functions multiply a floating-point number by a integral
power of 2 and return the result. In other words, it returns copy of the
given floating point number with the exponent increased by ex. A range
error may occur.

The `modf` functions break the argument `value` into integer and
fraction parts, each of which has the same sign as the argument. They
store the integer part in the object pointed to by `*iptr` and return
the fraction part. The `*iptr` is a floating-point type, rather than an
\"int\" type, because it might be used to store an integer like 1 000
000 000 000 000 000 000 which is too big to fit in an int.

The `scalbn` and `scalbln` compute `x` × `FLT_RADIX`^`n`^. `FLT_RADIX`
is the base of the floating-point system; if it is 2, the functions are
equivalent to `ldexp`.

``` c
 #include <math.h>
 float frexpf(float value, int *ex); /* C99 */
 double frexp(double value, int *ex);
 long double frexpl(long double value, int *ex); /* C99 */
 float ldexpf(float x, int ex); /* C99 */
 double ldexp(double x, int ex);
 long double ldexpl(long double x, int ex); /* C99 */
 float modff(float value, float *iptr); /* C99 */
 double modf(double value, double *iptr); 
 long double modfl(long double value, long double *iptr); /* C99 */
 float scalbnf(float x, int ex); /* C99 */
 double scalbn(double x, int ex); /* C99 */
 long double scalbnl(long double x, int ex); /* C99 */
 float scalblnf(float x, long int ex); /* C99 */
 double scalbln(double x, long int ex); /* C99 */
 long double scalblnl(long double x, long int ex); /* C99 */
```

Most C floating point libraries also implement the IEEE754-recommended
nextafter(), nextUp( ), and nextDown( ) functions.
[3

### The `log`, `log2`, `log1p`, and `log10` functions

The `log` functions compute the base-*e* natural logarithm of the
argument and return the result. A domain error occurs if the argument is
negative. A range error may occur if the argument is zero.

The `log1p` functions compute the base-*e* natural logarithm of one plus
the argument and return the result. A domain error occurs if the
argument is less than -1. A range error may occur if the argument is -1.

The `log10` functions compute the common (base-10) logarithm of the
argument and return the result. A domain error occurs if the argument is
negative. A range error may occur if the argument is zero.

The `log2` functions compute the base-2 logarithm of the argument and
return the result. A domain error occurs if the argument is negative. A
range error may occur if the argument is zero.

``` c
 #include <math.h>
 float logf(float x); /* C99 */
 double log(double x);
 long double logl(long double x); /* C99 */
 float log1pf(float x); /* C99 */
 double log1p(double x); /* C99 */
 long double log1pl(long double x); /* C99 */
 float log10f(float x); /* C99 */
 double log10(double x);
 long double log10l(long double x); /* C99 */
 float log2f(float x); /* C99 */
 double log2(double x); /* C99 */
 long double log2l(long double x); /* C99 */
```

### The `ilogb` and `logb` functions

The `ilogb` functions extract the exponent of `x` as a signed int value.
If `x` is zero, they return the value `FP_ILOGB0`; if `x` is infinite,
they return the value `INT_MAX`; if `x` is not-a-number they return the
value `FP_ILOGBNAN`; otherwise, they are equivalent to calling the
corresponding `logb` function and casting the returned value to type
`int`. A range error may occur if `x` is zero. `FP_ILOGB0` and
`FP_ILOGBNAN` are macros defined in `math.h`; `INT_MAX` is a macro
defined in `limits.h`.

The `logb` functions extract the exponent of `x` as a signed integer
value in floating-point format. If `x` is subnormal, it is treated as if
it were normalized; thus, for positive finite `x`, 1 ≤ `x` ×
`FLT_RADIX`^`-logb(x)`^ \< `FLT_RADIX` . `FLT_RADIX` is the radix for
floating-point numbers, defined in the `float.h` header.

``` c
 #include <math.h>
 int ilogbf(float x); /* C99 */
 int ilogb(double x); /* C99 */
 int ilogbl(long double x); /* C99 */
 float logbf(float x); /* C99 */
 double logb(double x); /* C99 */
 long double logbl(long double x); /* C99 */
```

## Power functions

### The `pow` functions

The `pow` functions compute `x` raised to the power `y` and return the
result. A domain error occurs if `x` is negative and `y` is not an
integral value. A domain error occurs if the result cannot be
represented when `x` is zero and `y` is less than or equal to zero. A
range error may occur.

``` c
 #include <math.h>
 float powf(float x, float y); /* C99 */
 double pow(double x, double y);
 long double powl(long double x, long double y); /* C99 */
```

### The `sqrt` functions

The `sqrt` functions compute the positive square root of `x` and return
the result. A domain error occurs if the argument is negative.

``` c
 #include <math.h>
 float sqrtf(float x); /* C99 */
 double sqrt(double x);
 long double sqrtl(long double x); /* C99 */
```

### The `cbrt` functions

The `cbrt` functions compute the cube root of `x` and return the result.

``` c
 #include <math.h>
 float cbrtf(float x); /* C99 */
 double cbrt(double x); /* C99 */
 long double cbrtl(long double x); /* C99 */
```

### The `hypot` functions

The `hypot` functions compute the square root of the sums of the squares
of `x` and `y`, without overflow or underflow, and return the result.

``` c
 #include <math.h>
 float hypotf(float x, float y); /* C99 */
 double hypot(double x, double y); /* C99 */
 long double hypotl(long double x, long double y); /* C99 */
```

## Nearest integer, absolute value, and remainder functions

### The `ceil` and `floor` functions

The `ceil` functions compute the smallest integral value not less than
`x` and return the result; the `floor` functions compute the largest
integral value not greater than `x` and return the result.

``` c
 #include <math.h>
 float ceilf(float x); /* C99 */
 double ceil(double x);
 long double ceill(long double x); /* C99 */
 float floorf(float x); /* C99 */
 double floor(double x);
 long double floorl(long double x); /* C99 */
```

### The `fabs` functions

The `fabs` functions compute the absolute value of a floating-point
number `x` and return the result.

``` c
 #include <math.h>
 float fabsf(float x); /* C99 */
 double fabs(double x); 
 long double fabsl(long double x); /* C99 */
```

### The `fmod` functions

The `fmod` functions compute the floating-point remainder of `x/y` and
return the value `x` - *i* \* `y`, for some integer *i* such that, if
`y` is nonzero, the result has the same sign as `x` and magnitude less
than the magnitude of `y`. If `y` is zero, whether a domain error occurs
or the `fmod` functions return zero is implementation-defined.

``` c
 #include <math.h>
 float fmodf(float x, float y); /* C99 */
 double fmod(double x, double y);
 long double fmodl(long double x, long double y); /* C99 */
```

### The `nearbyint`, `rint`, `lrint`, and `llrint` functions

The `nearbyint` functions round their argument to an integer value in
floating-point format, using the current rounding direction and without
raising the \"inexact\" floating-point exception.

The `rint` functions are similar to the `nearbyint` functions except
that they can raise the \"inexact\" floating-point exception if the
result differs in value from the argument.

The `lrint` and `llrint` functions round their arguments to the nearest
integer value according to the current rounding direction. If the result
is outside the range of values of the return type, the numeric result is
undefined and a range error may occur if the magnitude of the argument
is too large.

``` c
 #include <math.h>
 float nearbyintf(float x); /* C99 */
 double nearbyint(double x); /* C99 */
 long double nearbyintl(long double x); /* C99 */
 float rintf(float x); /* C99 */
 double rint(double x); /* C99 */
 long double rintl(long double x); /* C99 */
 long int lrintf(float x); /* C99 */
 long int lrint(double x); /* C99 */
 long int lrintl(long double x); /* C99 */
 long long int llrintf(float x); /* C99 */
 long long int llrint(double x); /* C99 */
 long long int llrintl(long double x); /* C99 */
```

### The `round`, `lround`, and `llround` functions

The `round` functions round the argument to the nearest integer value in
floating-point format, rounding halfway cases away from zero, regardless
of the current rounding direction.

The `lround` and `llround` functions round the argument to the nearest
integer value, rounding halfway cases away from zero, regardless of the
current rounding direction. If the result is outside the range of values
of the return type, the numeric result is undefined and a range error
may occur if the magnitude of the argument is too large.

``` c
 #include <math.h>
 float roundf(float x); /* C99 */
 double round(double x); /* C99 */
 long double roundl(long double x); /* C99 */
 long int lroundf(float x); /* C99 */
 long int lround(double x); /* C99 */
 long int lroundl(long double x); /* C99 */
 long long int llroundf(float x); /* C99 */
 long long int llround(double x); /* C99 */
 long long int llroundl(long double x); /* C99 */
```

### The `trunc` functions

The `trunc` functions round their argument to the integer value in
floating-point format that is nearest but no larger in magnitude than
the argument.

``` c
 #include <math.h>
 float truncf(float x); /* C99 */
 double trunc(double x); /* C99 */
 long double truncl(long double x); /* C99 */
```

### The `remainder` functions

The `remainder` functions compute the remainder `x` REM `y` as defined
by IEC 60559. The definition reads, \"When *y* ≠ 0, the remainder *r* =
*x* REM *y* is defined regardless of the rounding mode by the
mathematical reduction *r* = *x* - *ny*, where *n* is the integer
nearest the exact value of *x*/*y*; whenever \|*n* - *x*/*y*\| = ½, then
*n* is even. Thus, the remainder is always exact. If *r* = 0, its sign
shall be that of *x*.\" This definition is applicable for all
implementations.

``` c
 #include <math.h>
 float remainderf(float x, float y); /* C99 */
 double remainder(double x, double y); /* C99 */
 long double remainderl(long double x, long double y); /* C99 */
```

### The `remquo` functions

The `remquo` functions return the same remainder as the `remainder`
functions. In the object pointed to by `quo`, they store a value whose
sign is the sign of `x`/`y` and whose magnitude is congruent modulo 2^n^
to the magnitude of the integral quotient of `x`/`y`, where *n* is an
implementation-defined integer greater than or equal to 3.

``` c
 #include <math.h>
 float remquof(float x, float y, int *quo); /* C99 */
 double remquo(double x, double y, int *quo); /* C99 */
 long double remquol(long double x, long double y, int *quo); /* C99 */
```

## Error and gamma functions

The `erf` functions compute the error function of the argument
$\frac{2}{\sqrt{\pi}}\int_{0}^x e^{-t^2}\,\mathrm dt$

The `erfc` functions compute the complimentary error function of the
argument (that is, 1 - erf x). For the `erfc` functions, a range error
may occur if the argument is too large.

The `lgamma` functions compute the natural logarithm of the absolute
value of the gamma of the argument (that is, log~*e*~\|Γ(x)\|). A range
error may occur if the argument is a negative integer or zero.

The `tgamma` functions compute the gamma of the argument (that is,
Γ(x)). A domain error occurs if the argument is a negative integer or if
the result cannot be represented when the argument is zero. A range
error may occur.

``` c
 #include <math.h>
 float erff(float x); /* C99 */
 double erf(double x); /* C99 */
 long double erfl(long double x); /* C99 */
 float erfcf(float x); /* C99 */
 double erfc(double x); /* C99 */
 long double erfcl(long double x); /* C99 */
 float lgammaf(float x); /* C99 */
 double lgamma(double x); /* C99 */
 long double lgammal(long double x); /* C99 */
 float tgammaf(float x); /* C99 */
 double tgamma(double x); /* C99 */
 long double tgammal(long double x); /* C99 */
```

## References

{{-}} 

fr:Programmation
C/Mathématiques
pl:C/Zaawansowane operacje
matematyczne

[^1]: 1
    Why do you have to link the math library in C?

[^2]: 2
    Why do I have to explicitly link with libm?
