Standard Library Mathematical Functions in C

Key Takeaways
  • 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_PI for the value of \pi and M_E for the value of e.
  • Mathematical functions are available in three variants to support the float, double and long double data 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 \pi
M_PI_2 1.57079632679489661923 Value of \frac{\pi}{2}
M_PI_4 0.78539816339744830962 Value of \frac{\pi}{4}
M_1_PI 0.31830988618379067154 Value of \frac{1}{\pi}
M_2_PI 0.63661977236758134308 Value of \frac{2}{\pi}
M_2_SQRTPI 1.12837916709551257390 Value of \frac{2}{\sqrt{\pi}}
M_E 2.71828182845904523536 Value of e (base of natural logarithms)
M_SQRT2 1.41421356237309504880 Value of \sqrt{2}
M_SQRT1_2 0.70710678118654752440 Value of \frac{1}{\sqrt{2}}
M_LN2 0.69314718055994530942 Value of \ln(2)
M_LN10 2.30258509299404568402 Value of \ln(10)
M_LOG2E 1.44269504088896340736 Value of \log_2(e)
M_LOG10E 0.43429448190325182765 Value of \log_{10}(e)
Table 1: Table of mathematical constants defined in the C standard library

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) \sin(x) in radians. Returns float. C99
sin(double x) \sin(x) in radians. Returns double.
sinl(long double x) \sin(x) in radians. Returns long double. C99
cosf(float x) \cos(x) in radians. Returns float. C99
cos(double x) \cos(x) in radians. Returns double.
cosl(long double x) \cos(x) in radians. Returns long double. C99
tanf(float x) \tan(x) in radians. Returns float. C99
tan(double x) \tan(x) in radians. Returns double.
tanl(long double x) \tan(x) in radians. Returns long double. C99
Table 2: Trigonometric functions of the C standard library
Function Description Notes
asinf(float x) \arcsin(x) in radians. Returns float. C99
asin(double x) \arcsin(x) in radians. Returns double.
asinl(long double x) \arcsin(x) in radians. Returns long double. C99
acosf(float x) \arccos(x) in radians. Returns float. C99
acos(double x) \arccos(x) in radians. Returns double.
acosl(long double x) \arccos(x) in radians. Returns long double. C99
atanf(float x) \arctan(x) in radians. Returns float. C99
atan(double x) \arctan(x) in radians. Returns double.
atanl(long double x) \arctan(x) in radians. Returns long double. C99
atan2f(float y, float x) \arctan\left(\frac{y}{x}\right) in radians. Returns float. C99
atan2(double y, double x) \arctan\left(\frac{y}{x}\right) in radians. Returns double.
atan2l(long double y, long double x) \arctan\left(\frac{y}{x}\right) in radians. Returns long double. C99
Table 3: Inverse trigonometric functions of the C standard library

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:

  • \text{radians} = \text{degrees} \cdot \frac{\pi}{180}
  • \text{degrees} = \text{radians} \cdot \frac{180}{\pi}

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 [0, \pi], while asin and atan return values in the interval [-\frac{\pi}{2}, \frac{\pi}{2}].

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 (-\pi, \pi]. A call to 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) \sinh(x) Returns float. C99
sinh(double x) \sinh(x) Returns double.
sinhl(long double x) \sinh(x) Returns long double. C99
coshf(float x) \cosh(x) Returns float. C99
cosh(double x) \cosh(x) Returns double.
coshl(long double x) \cosh(x) Returns long double. C99
tanhf(float x) \tanh(x) Returns float. C99
tanh(double x) \tanh(x) Returns double.
tanhl(long double x) \tanh(x) Returns long double. C99
Table 4: Hyperbolic functions of the C standard library
Function Description Notes
asinhf(float x) \operatorname{arcsinh}(x) Returns float. C99
asinh(double x) \operatorname{arcsinh}(x) Returns double. C99
asinhl(long double x) \operatorname{arcsinh}(x) Returns long double. C99
acoshf(float x) \operatorname{arccosh}(x) Returns float. C99
acosh(double x) \operatorname{arccosh}(x) Returns double. C99
acoshl(long double x) \operatorname{arccosh}(x) Returns long double. C99
atanhf(float x) \operatorname{arctanh}(x) Returns float. C99
atanh(double x) \operatorname{arctanh}(x) Returns double. C99
atanhl(long double x) \operatorname{arctanh}(x) Returns long double. C99
Table 5: Inverse hyperbolic functions of the C standard library

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) e^x Returns float. C99
exp(double x) e^x Returns double.
expl(long double x) e^x Returns long double. C99
logf(float x) \ln(x) Returns float. C99
log(double x) \ln(x) Returns double.
logl(long double x) \ln(x) Returns long double. C99
log10f(float x) \log_{10}(x) Returns float. C99
log10(double x) \log_{10}(x) Returns double.
log10l(long double x) \log_{10}(x) Returns long double. C99
exp2f(float x) 2^x Returns float. C99
exp2(double x) 2^x Returns double. C99
exp2l(long double x) 2^x Returns long double. C99
expm1f(float x) e^x - 1 Returns float. C99
expm1(double x) e^x - 1 Returns double. C99
expm1l(long double x) e^x - 1 Returns long double. C99
log1pf(float x) \ln(1 + x) Returns float. C99
log1p(double x) \ln(1 + x) Returns double. C99
log1pl(long double x) \ln(1 + x) Returns long double. C99
log2f(float x) \log_2(x) Returns float. C99
log2(double x) \log_2(x) Returns double. C99
log2l(long double x) \log_2(x) Returns long double. C99
ilogbf(float x) Integer part of \log_2(x). Returns int. C99
ilogb(double x) Integer part of \log_2(x). Returns int. C99
ilogbl(long double x) Integer part of \log_2(x). Returns int. C99
logbf(float x) Exponent of x in base 2. Returns int. C99
logb(double x) Exponent of x in base 2. Returns int. C99
logbl(long double x) Exponent of x in base 2. Returns int. C99
Table 6: Exponential and logarithmic functions of the C standard library

All these functions deal with the natural exponential (base e) or with the natural logarithm, except those specifically indicated as logarithms in base 10 or base 2.

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 e, 10 or 2, you can use the change of base formula:

\log_b(x) = \frac{\log_k(x)}{\log_k(b)}

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 b^e. Returns float. C99
pow(double b, double e) Calculates b^e. Returns double.
powl(long double b, long double e) Calculates b^e. Returns long double. C99
sqrtf(float x) Calculates \sqrt{x}. Returns float. C99
sqrt(double x) Calculates \sqrt{x}. Returns double.
sqrtl(long double x) Calculates \sqrt{x}. Returns 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 f \cdot 2^e. Returns float. C99
ldexp(double f, int e) Calculates f \cdot 2^e. Returns double.
ldexpl(long double f, int e) Calculates f \cdot 2^e. Returns long double. C99
cbrtf(float x) Calculates \sqrt[3]{x}. Returns float. C99
cbrt(double x) Calculates \sqrt[3]{x}. Returns double. C99
cbrtl(long double x) Calculates \sqrt[3]{x}. Returns long double. C99
hypotf(float x, float y) Calculates \sqrt{x^2 + y^2}. Returns float. C99
hypot(double x, double y) Calculates \sqrt{x^2 + y^2}. Returns double.
hypotl(long double x, long double y) Calculates \sqrt{x^2 + y^2}. Returns long double. C99
Table 7: Power and root functions of the C standard library

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.
Table 8: Functions for absolute value and sign of the C standard library

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
Table 9: Gamma and error functions of the C standard library

Some important observations regarding these functions:

  • The erf, erff and erfl functions calculate the error function, which is useful in statistics and probability:

    \operatorname{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2} dt
  • The erfc, erccf and erfcl functions calculate the complementary error function:

    \operatorname{erfc}(x) = 1 - \operatorname{erf}(x)
  • The gamma function, \Gamma(x), is a generalization of the factorial function for real and complex numbers. For positive integers it holds:

    \Gamma(n) = (n-1)!

    For real and complex values, the gamma function is more complex and is defined through an improper integral:

    \Gamma(x) = \int_0^{\infty} t^{x-1} e^{-t} dt

    The tgamma and lgamma functions calculate respectively the gamma function and its natural logarithm:

    • tgamma(x) returns \Gamma(x)
    • lgamma(x) returns \ln(|\Gamma(x)|)

    The lgamma_r function also provides the sign of the gamma function through the signgamp parameter. Often using the logarithmic function is preferable to avoid overflow problems with large values of x.

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
Table 10: Fused Multiply-Add functions of the C standard library

In practice, these functions, given the numbers x, y and z as input, calculate the following mathematical expression:

\text{FMA}(x, y, z) = (x \cdot y) + z

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:

  1. If present, being performed in hardware this operation is faster compared to performing the two operations separately;
  2. 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.