Standard Library Mathematical Functions in C
- The C standard mathematical library, defined in the
<math.h>header, offers a wide range of mathematical functions to perform common operations such as trigonometric, exponential, logarithmic calculations and more. - The library includes useful numerical constants such as
M_PIfor the value ofand M_Efor the value of. - Mathematical functions are available in three variants to support the
float,doubleandlong doubledata types, allowing greater flexibility in the use of numerical precisions.
Numerical Constants
The C standard mathematical library defines some useful numerical constants for mathematical operations. These constants are defined as macros in the <math.h> header and include:
| Macro | Approximate Value | Description |
|---|---|---|
M_PI |
3.14159265358979323846 | Value of |
M_PI_2 |
1.57079632679489661923 | Value of |
M_PI_4 |
0.78539816339744830962 | Value of |
M_1_PI |
0.31830988618379067154 | Value of |
M_2_PI |
0.63661977236758134308 | Value of |
M_2_SQRTPI |
1.12837916709551257390 | Value of |
M_E |
2.71828182845904523536 | Value of |
M_SQRT2 |
1.41421356237309504880 | Value of |
M_SQRT1_2 |
0.70710678118654752440 | Value of |
M_LN2 |
0.69314718055994530942 | Value of |
M_LN10 |
2.30258509299404568402 | Value of |
M_LOG2E |
1.44269504088896340736 | Value of |
M_LOG10E |
0.43429448190325182765 | Value of |
In reality, these macros are not part of the C standard, but are widely supported by the most common compilers as extensions. However, it is important to note that not all compilers guarantee the presence of these macros, so it is good practice to check the documentation of the compiler in use.
Trigonometric Functions
The C standard mathematical library provides several trigonometric functions to calculate the values of sine, cosine, tangent functions and their inverses:
| Function | Description | Notes |
|---|---|---|
sinf(float x) |
float. |
C99 |
sin(double x) |
double. |
|
sinl(long double x) |
long double. |
C99 |
cosf(float x) |
float. |
C99 |
cos(double x) |
double. |
|
cosl(long double x) |
long double. |
C99 |
tanf(float x) |
float. |
C99 |
tan(double x) |
double. |
|
tanl(long double x) |
long double. |
C99 |
| Function | Description | Notes |
|---|---|---|
asinf(float x) |
float. |
C99 |
asin(double x) |
double. |
|
asinl(long double x) |
long double. |
C99 |
acosf(float x) |
float. |
C99 |
acos(double x) |
double. |
|
acosl(long double x) |
long double. |
C99 |
atanf(float x) |
float. |
C99 |
atan(double x) |
double. |
|
atanl(long double x) |
long double. |
C99 |
atan2f(float y, float x) |
float. |
C99 |
atan2(double y, double x) |
double. |
|
atan2l(long double y, long double x) |
long double. |
C99 |
An important observation concerns the unit of measurement for angles used by these functions. All trigonometric functions of the C standard mathematical library operate in radians, not degrees. Therefore, if you want to use degrees, it is necessary to convert values between degrees and radians using the following formulas:
Moreover, often due to numerical rounding, it is not guaranteed that the result provided by the cos function, for example, passed as input to the acos function will return exactly the original value.
Furthermore, the acos function returns values only in the interval asin and atan return values in the interval
The atan2 function is particularly useful because it considers the sign of both arguments to determine the correct quadrant of the resulting angle, returning values in the interval atan(x) is equivalent to atan2(x, 1.0).
Hyperbolic Functions
The C standard mathematical library also includes functions to calculate hyperbolic functions and their inverses:
| Function | Description | Notes |
|---|---|---|
sinhf(float x) |
float. |
C99 |
sinh(double x) |
double. |
|
sinhl(long double x) |
long double. |
C99 |
coshf(float x) |
float. |
C99 |
cosh(double x) |
double. |
|
coshl(long double x) |
long double. |
C99 |
tanhf(float x) |
float. |
C99 |
tanh(double x) |
double. |
|
tanhl(long double x) |
long double. |
C99 |
| Function | Description | Notes |
|---|---|---|
asinhf(float x) |
float. |
C99 |
asinh(double x) |
double. |
C99 |
asinhl(long double x) |
long double. |
C99 |
acoshf(float x) |
float. |
C99 |
acosh(double x) |
double. |
C99 |
acoshl(long double x) |
long double. |
C99 |
atanhf(float x) |
float. |
C99 |
atanh(double x) |
double. |
C99 |
atanhl(long double x) |
long double. |
C99 |
Note that also in this case, hyperbolic functions operate on values in radians and not in degrees.
Exponential and Logarithmic Functions
The C standard mathematical library provides functions to calculate exponentials and logarithms:
| Function | Description | Notes |
|---|---|---|
expf(float x) |
float. |
C99 |
exp(double x) |
double. |
|
expl(long double x) |
long double. |
C99 |
logf(float x) |
float. |
C99 |
log(double x) |
double. |
|
logl(long double x) |
long double. |
C99 |
log10f(float x) |
float. |
C99 |
log10(double x) |
double. |
|
log10l(long double x) |
long double. |
C99 |
exp2f(float x) |
float. |
C99 |
exp2(double x) |
double. |
C99 |
exp2l(long double x) |
long double. |
C99 |
expm1f(float x) |
float. |
C99 |
expm1(double x) |
double. |
C99 |
expm1l(long double x) |
long double. |
C99 |
log1pf(float x) |
float. |
C99 |
log1p(double x) |
double. |
C99 |
log1pl(long double x) |
long double. |
C99 |
log2f(float x) |
float. |
C99 |
log2(double x) |
double. |
C99 |
log2l(long double x) |
long double. |
C99 |
ilogbf(float x) |
Integer part of int. |
C99 |
ilogb(double x) |
Integer part of int. |
C99 |
ilogbl(long double x) |
Integer part of int. |
C99 |
logbf(float x) |
Exponent of int. |
C99 |
logb(double x) |
Exponent of int. |
C99 |
logbl(long double x) |
Exponent of int. |
C99 |
All these functions deal with the natural exponential (base
Moreover, calculating the logarithm of numbers very close to 1 can lead to significant rounding errors. For this reason, the log1p and expm1 functions were introduced to provide greater precision in these specific cases.
To calculate the logarithm in bases other than
So, for example, to calculate the base 3 logarithm of a number x, you can use:
double log_base_3(double x) {
return log(x) / log(3.0);
}
Power and Root Functions
The C standard mathematical library includes functions to calculate powers and roots:
| Function | Description | Notes |
|---|---|---|
powf(float b, float e) |
Calculates float. |
C99 |
pow(double b, double e) |
Calculates double. |
|
powl(long double b, long double e) |
Calculates long double. |
C99 |
sqrtf(float x) |
Calculates float. |
C99 |
sqrt(double x) |
Calculates double. |
|
sqrtl(long double x) |
Calculates long double. |
C99 |
frexpf(float x, int *exponent) |
Decomposes x into fraction and power of 2. Returns float. |
C99 |
frexp(double x, int *exponent) |
Decomposes x into fraction and power of 2. Returns double. |
|
frexpl(long double x, int *exponent) |
Decomposes x into fraction and power of 2. Returns long double. |
C99 |
ldexpf(float f, int e) |
Calculates float. |
C99 |
ldexp(double f, int e) |
Calculates double. |
|
ldexpl(long double f, int e) |
Calculates long double. |
C99 |
cbrtf(float x) |
Calculates float. |
C99 |
cbrt(double x) |
Calculates double. |
C99 |
cbrtl(long double x) |
Calculates long double. |
C99 |
hypotf(float x, float y) |
Calculates float. |
C99 |
hypot(double x, double y) |
Calculates double. |
|
hypotl(long double x, long double y) |
Calculates long double. |
C99 |
Functions for Absolute Value and Sign
The C standard mathematical library includes functions to calculate the absolute value and sign of a number:
| Function | Description | Notes |
|---|---|---|
fabsf(float x) |
Calculates the absolute value of x. Returns float. |
C99 |
fabs(double x) |
Calculates the absolute value of x. Returns double. |
|
fabsl(long double x) |
Calculates the absolute value of x. Returns long double. |
C99 |
copysignf(float x, float y) |
Returns x with the sign of y. Returns float. |
C99 |
copysign(double x, double y) |
Returns x with the sign of y. Returns double. |
|
copysignl(long double x, long double y) |
Returns x with the sign of y. Returns long double. |
C99 |
signbitf(float x) |
Returns true if the sign of x is negative. |
Returns int. |
signbit(double x) |
Returns true if the sign of x is negative. |
Returns int. |
signbitl(long double x) |
Returns true if the sign of x is negative. |
Returns int. |
The copysign functions are particularly useful when you want to manipulate the sign of a number without altering its absolute value.
For example, copysign(x, 1.0) returns the absolute value of x, while copysign(x, -1.0) returns the absolute value of x with negative sign.
The signbit functions, instead, are useful to verify if a number is negative, regardless of its absolute value. These functions are much more reliable compared to a simple comparison with zero, since they also consider the case of negative zero represented in floating point.
Gamma Function and Standard Error Function
The C standard mathematical library includes functions to calculate the gamma function and the error function:
| Function | Description | Notes |
|---|---|---|
tgammaf(float x) |
Calculates the gamma function of x. Returns float. |
C99 |
tgamma(double x) |
Calculates the gamma function of x. Returns double. |
|
tgammal(long double x) |
Calculates the gamma function of x. Returns long double. |
C99 |
lgammaf(float x) |
Calculates the natural logarithm of the gamma function of x. Returns float. |
C99 |
lgamma(double x) |
Calculates the natural logarithm of the gamma function of x. Returns double. |
|
lgammal(long double x) |
Calculates the natural logarithm of the gamma function of x. Returns long double. |
C99 |
erff(float x) |
Calculates the error function of x. Returns float. |
C99 |
erf(double x) |
Calculates the error function of x. Returns double. |
|
erfl(long double x) |
Calculates the error function of x. Returns long double. |
C99 |
erfcf(float x) |
Calculates the complementary error function of x. Returns float. |
C99 |
erfc(double x) |
Calculates the complementary error function of x. Returns double. |
|
erfcl(long double x) |
Calculates the complementary error function of x. Returns long double. |
C99 |
lgamma_r(double x, int *signgamp) |
Calculates the natural logarithm of the gamma function of x and sets the sign in signgamp. Returns double. |
C99 |
Some important observations regarding these functions:
-
The
erf,erffanderflfunctions calculate the error function, which is useful in statistics and probability: -
The
erfc,erccfanderfclfunctions calculate the complementary error function: -
The gamma function,
, is a generalization of the factorial function for real and complex numbers. For positive integers it holds: For real and complex values, the gamma function is more complex and is defined through an improper integral:
The
tgammaandlgammafunctions calculate respectively the gamma function and its natural logarithm:tgamma(x)returnslgamma(x)returns
The
lgamma_rfunction also provides the sign of the gamma function through thesigngampparameter. Often using the logarithmic function is preferable to avoid overflow problems with large values ofx.
Functions for Combined Multiplication and Addition (Fused Multiply-Add)
An important functionality offered by the C standard mathematical library is the ability to perform combined multiplication and addition operations, known as Fused Multiply-Add (FMA).
The FMA functions are:
| Function | Description | Notes |
|---|---|---|
fmaf(float x, float y, float z) |
Calculates (x * y) + z with a single operation. Returns float. |
C99 |
fma(double x, double y, double z) |
Calculates (x * y) + z with a single operation. Returns double. |
C99 |
fmal(long double x, long double y, long double z) |
Calculates (x * y) + z with a single operation. Returns long double. |
C99 |
In practice, these functions, given the numbers
These functions were added to the standard since many modern CPUs offer the FMA operation in hardware that multiplies and adds in one go. By calling this function, we are telling the compiler that we want to exploit the corresponding hardware instruction (if available) which has two advantages:
- If present, being performed in hardware this operation is faster compared to performing the two operations separately;
- This instruction performs a rounding operation only once, instead of twice, thus producing a more accurate result.
It is particularly useful in those numerical algorithms that perform a series of multiplications and additions. For example algorithms for calculating the dot product between two vectors, the multiplication of two matrices or the calculation of the FFT (Fast Fourier Transform).
To know if the underlying platform and compiler support this function, you can check if the FP_FAST_FMA macro has been defined. If yes, calling fma should be faster than (or at least as fast as) performing a separate multiplication and addition operation.
There are also the FP_FAST_FMAF and FP_FAST_FMAL macros that perform the same role for the fmaf and fmal functions respectively.