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
| Function | Computes |
|---|---|
sqrt(x), cbrt(x) | Square root, cube root |
pow(x, y) | xy |
fabs(x) | Absolute value of a double |
floor, ceil, round, trunc | Rounding down, up, to nearest, toward zero |
fmod(x, y) | Floating-point remainder |
exp, log, log10, log2 | ex and logarithms |
sin, cos, tan, atan2 | Trigonometry (in radians) |
hypot(x, y) | √(x² + y²) without overflow |
fmin, fmax | Smaller / larger of two doubles |
#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; }
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:
#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; }
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
#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; }
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
#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; }
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:
#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.
Monthly payment: 1111.66 Total repaid: 333499.49