math.h is the standard mathematical function library for floating-point arithmetic. It covers trigonometry, exponentiation, logarithms, rounding, and a handful of utility functions. Every function operates on double by default; append f for float (sinf, sqrtf) or l for long double (sinl). You have to link with -lm on most systems.
#include <math.h> // compile with: -lm double y = sqrt(2.0); // 1.4142... double s = sin(M_PI / 6); // 0.5 (M_PI is a common extension, not strictly standard) double e = exp(1.0); // e ≈ 2.71828 double l = log(M_E); // 1.0 (natural log) double p = pow(2.0, 10.0); // 1024.0 double a = fabs(-3.5); // 3.5 double r = floor(3.7); // 3.0 double c = ceil(3.2); // 4.0 double t = round(3.5); // 4.0 (half away from zero)
C99 added several functions that are more numerically stable than the naive equivalents:
hypot(3.0, 4.0) // sqrt(3²+4²) = 5.0 without intermediate overflow cbrt(27.0) // cube root = 3.0 log2(1024.0) // 10.0 log1p(1e-15) // log(1+x), accurate for small x expm1(1e-15) // exp(x)-1, accurate for small x
Domain errors (e.g. sqrt(-1)) return NaN and set errno to EDOM. Range errors (e.g. exp(1e308)) return HUGE_VAL and set errno to ERANGE. The C99 macros isnan, isinf, and isfinite test the class of a result without triggering the quirks of comparing NaN with ==.
// compile: gcc -O2 -o mathdemo mathdemo.c -lm // run: ./mathdemo // description: Pythagorean triple, domain error, and log1p accuracy demo #include <errno.h> #include <math.h> #include <stdio.h> #include <string.h> int main(void) { // basic: 3-4-5 right triangle printf("hypot(3,4) = %.1f\n", hypot(3.0, 4.0)); // domain error: sqrt of negative number errno = 0; double bad = sqrt(-1.0); printf("sqrt(-1) = %g isnan=%d errno=%s\n", bad, isnan(bad), strerror(errno)); // accuracy: log1p vs log(1+x) for very small x double x = 1e-15; printf("log(1+x) = %.20f\n", log(1.0 + x)); // loses precision printf("log1p(x) = %.20f\n", log1p(x)); // accurate return 0; }
The log1p vs log(1+x) comparison is instructive: for very small x, 1.0 + x rounds to exactly 1.0 in double precision, so log(1.0 + x) returns 0. log1p(x) is implemented to avoid this cancellation and returns the correct small value. This is the kind of subtlety that <math.h> addresses if you use the right function.