The Math Library

C's <math.h> header provides square roots, powers, trigonometry, logarithms and rounding, and <stdlib.h> adds integer helpers and random numbers. This lesson tours the functions you'll reach for most often.

Linking the maths library

On Linux, the maths functions live in a separate library, so add -lm at the end of the compile command; on macOS and Windows it's included automatically:

$
gcc -std=c17 -Wall main.c -o main -lm

Forgetting it gives a linker error like "undefined reference to `sqrt'" (lesson 4).

Common functions

FunctionComputes
sqrt(x), cbrt(x)Square root, cube root
pow(x, y)xy
fabs(x)Absolute value of a double
floor, ceil, round, truncRounding down, up, to nearest, toward zero
fmod(x, y)Floating-point remainder
exp, log, log10, log2ex and logarithms
sin, cos, tan, atan2Trigonometry (in radians)
hypot(x, y)√(x² + y²) without overflow
fmin, fmaxSmaller / larger of two doubles
C
#include <stdio.h>
#include <math.h>

int main(void) {
    printf("sqrt(2)      = %.6f\n", sqrt(2.0));
    printf("pow(2, 10)   = %.0f\n", pow(2, 10));
    printf("cbrt(27)     = %.1f\n", cbrt(27));
    printf("hypot(3, 4)  = %.1f\n", hypot(3, 4));
    printf("log10(1000)  = %.1f\n", log10(1000));
    printf("exp(1)       = %.6f\n", exp(1));
    printf("fmod(10, 3)  = %.1f\n", fmod(10, 3));
    return 0;
}
Output
sqrt(2)      = 1.414214
pow(2, 10)   = 1024
cbrt(27)     = 3.0
hypot(3, 4)  = 5.0
log10(1000)  = 3.0
exp(1)       = 2.718282
fmod(10, 3)  = 1.0

All of these take and return double. There are float versions with an f suffix (sqrtf) and long double versions with l (sqrtl).

Trigonometry

Angles are in radians. Standard C has no π constant; M_PI is a common extension, but defining your own is portable:

C
#include <stdio.h>
#include <math.h>

#define PI 3.14159265358979323846

int main(void) {
    for (int degrees = 0; degrees <= 90; degrees += 30) {
        double rad = degrees * PI / 180.0;
        printf("%2d deg: sin %.3f, cos %.3f\n", degrees, sin(rad), cos(rad));
    }
    double angle = atan2(1.0, 1.0) * 180.0 / PI;
    printf("direction of (1, 1): %.0f degrees\n", angle);
    return 0;
}
Output
 0 deg: sin 0.000, cos 1.000
30 deg: sin 0.500, cos 0.866
60 deg: sin 0.866, cos 0.500
90 deg: sin 1.000, cos 0.000
direction of (1, 1): 45 degrees

Rounding

C
#include <stdio.h>
#include <math.h>

int main(void) {
    double values[] = { 2.4, 2.5, -2.5, -2.6 };
    printf("%6s %6s %6s %6s %6s\n", "x", "floor", "ceil", "round", "trunc");
    for (int i = 0; i < 4; i++) {
        double x = values[i];
        printf("%6.1f %6.1f %6.1f %6.1f %6.1f\n", x, floor(x), ceil(x), round(x), trunc(x));
    }
    printf("Round 2.345 to 2 places: %.2f\n", round(2.345 * 100) / 100);
    return 0;
}
Output
     x  floor   ceil  round  trunc
   2.4    2.0    3.0    2.0    2.0
   2.5    2.0    3.0    3.0    2.0
  -2.5   -3.0   -2.0   -3.0   -2.0
  -2.6   -3.0   -2.0   -3.0   -2.0
Round 2.345 to 2 places: 2.35

round rounds halves away from zero. To round to decimal places for display, printf's precision (%.2f) is usually all you need.

Integer helpers in stdlib.h

C
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    printf("abs(-7) = %d, labs(-7000000000) = %ld\n", abs(-7), labs(-7000000000L));
    div_t d = div(17, 5);
    printf("17 / 5 = %d remainder %d\n", d.quot, d.rem);
    return 0;
}
Output
abs(-7) = 7, labs(-7000000000) = 7000000000
17 / 5 = 3 remainder 2

Note abs is for int; using it on a double would truncate — use fabs for floating point.

Random numbers

rand() returns a pseudo-random integer from 0 to RAND_MAX. Seed it once with srand, usually from the current time, or you'll get the same sequence every run:

C
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    srand((unsigned) time(NULL));        // seed once, at start-up
    for (int i = 0; i < 5; i++) {
        int die = rand() % 6 + 1;        // 1 to 6
        printf("%d ", die);
    }
    printf("\n");
    return 0;
}

With a fixed seed, the sequence is repeatable — handy for testing. rand is fine for games and simulations, but not for anything security-related such as passwords or tokens; use your operating system's secure random source for that (for example getrandom on Linux or arc4random on macOS and BSD).

Errors and special results

Invalid inputs produce special values rather than crashes: sqrt(-1) gives NaN and log(0) gives −infinity. Check results with isnan and isinf (lesson 9) when inputs come from outside.

Try it yourself

Calculate monthly repayments on a loan: payment = P·r / (1 − (1 + r)−n), where r is the monthly interest rate and n the number of months.

Try it yourself · main.c
Edit the code, copy it into main.c, then compile and run it with cc -std=c17 -Wall main.c -o main && ./main. How to set up a C compiler
Output
Monthly payment: 1111.66
Total repaid:    333499.49