Nearby lessons

82 of 124

C - Math Functions

The <math.h> library gives C its mathematics: sqrt, pow, fabs, ceil, floor, round, trigonometry, logarithms and more. Learn the full set, plus the -lm linker flag that trips up every beginner.

The Essential Functions

FunctionReturnsExampleResult
sqrt(x)Square rootsqrt(25)5.0
pow(x, y)x to the power ypow(2, 10)1024.0
fabs(x)Absolute valuefabs(-7.5)7.5
ceil(x)Round upceil(4.1)5.0
floor(x)Round downfloor(4.9)4.0
round(x)Nearest integerround(4.5)5.0
fmod(x, y)Floating remainderfmod(10.5, 3)1.5
Example01
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4int main()
5{
6 printf("sqrt(144) = %.2f\n", sqrt(144.0));
7 printf("pow(2, 10) = %.0f\n", pow(2.0, 10.0));
8 printf("fabs(-7.5) = %.2f\n", fabs(-7.5));
9 printf("fmod(10.5, 3) = %.2f\n", fmod(10.5, 3.0));
10 return 0;
11}
Output
sqrt(144)      = 12.00
pow(2, 10)     = 1024
fabs(-7.5)     = 7.50
fmod(10.5, 3)  = 1.50

Compiling — The -lm Flag

The error every beginner hits: undefined reference to 'sqrt'. Including <math.h> only tells the compiler what sqrt looks like — you must also tell the linker where the code lives. On Linux and macOS with gcc, add -lm:
Example02
CCode Cell
1/* Correct compilation on Linux / macOS: */
2gcc program.c -o program -lm
3 
4/* Without -lm:
5 /tmp/cc123.o: undefined reference to 'sqrt'
6 collect2: error: ld returned 1 exit status */
7 
8/* On Windows with MinGW or MSVC, -lm is usually unnecessary */
Output
Compiles cleanly with -lm

The Three Rounding Functions

ceil always goes up, floor always goes down, round goes to the nearest. Watch how they differ on negatives:

Example03
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4int main()
5{
6 double values[4] = {4.2, 4.7, -4.2, -4.7};
7 int i;
8 
9 printf("value ceil floor round\n");
10 for (i = 0; i < 4; i++)
11 printf("%5.1f %5.0f %5.0f %5.0f\n",
12 values[i], ceil(values[i]),
13 floor(values[i]), round(values[i]));
14 return 0;
15}
Output
value   ceil  floor  round
  4.2      5      4      4
  4.7      5      4      5
 -4.2     -4     -5     -4
 -4.7     -4     -5     -5

fabs vs abs

Two different functions in two different headers. Using abs on a double truncates it first:

Example04
CCode Cell
1#include <stdio.h>
2#include <math.h>
3#include <stdlib.h>
4 
5int main()
6{
7 printf("abs(-7) = %d (int, stdlib.h)\n", abs(-7));
8 printf("fabs(-7.85) = %.2f (double, math.h)\n", fabs(-7.85));
9 printf("abs(-7.85) = %d (WRONG - truncates first)\n",
10 abs((int) -7.85));
11 return 0;
12}
Output
abs(-7)      = 7      (int,    stdlib.h)
fabs(-7.85)  = 7.85  (double, math.h)
abs(-7.85)   = 7      (WRONG - truncates first)

Trigonometry Works in Radians

sin, cos and tan expect radians. Convert from degrees with degrees × π / 180:

Example05
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4#define PI 3.14159265358979
5 
6double toRadians(double degrees) { return degrees * PI / 180.0; }
7 
8int main()
9{
10 double deg[4] = {0, 30, 45, 90};
11 int i;
12 
13 printf("degrees sin cos\n");
14 for (i = 0; i < 4; i++)
15 {
16 double r = toRadians(deg[i]);
17 printf("%7.0f %7.4f %7.4f\n", deg[i], sin(r), cos(r));
18 }
19 return 0;
20}
Output
degrees      sin      cos
      0   0.0000   1.0000
     30   0.5000   0.8660
     45   0.7071   0.7071
     90   1.0000   0.0000

Logarithms and Exponentials

log is the natural logarithm (base e); log10 is base 10. exp(x) computes e to the power x:

Example06
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4int main()
5{
6 printf("log(2.718282) = %.4f (natural log)\n", log(2.718282));
7 printf("log10(1000) = %.4f (base 10)\n", log10(1000.0));
8 printf("log2(1024) = %.4f (base 2)\n", log2(1024.0));
9 printf("exp(1) = %.6f (e itself)\n", exp(1.0));
10 return 0;
11}
Output
log(2.718282) = 1.0000  (natural log)
log10(1000)   = 3.0000  (base 10)
log2(1024)    = 10.0000  (base 2)
exp(1)        = 2.718282  (e itself)

A Practical Example — Distance

sqrt and pow together give the classic distance formula:

Example07
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4double distance(double x1, double y1, double x2, double y2)
5{
6 return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
7}
8 
9int main()
10{
11 printf("(0,0) to (3,4) = %.2f\n", distance(0, 0, 3, 4));
12 printf("(1,1) to (4,5) = %.2f\n", distance(1, 1, 4, 5));
13 printf("(2,3) to (2,10) = %.2f\n", distance(2, 3, 2, 10));
14 return 0;
15}
Output
(0,0) to (3,4)  = 5.00
(1,1) to (4,5)  = 5.00
(2,3) to (2,10) = 7.00

Rounding to Decimal Places

printf rounds for display only. To round the stored value, scale up, round, and scale back:

Example08
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4double roundTo(double value, int places)
5{
6 double factor = pow(10.0, places);
7 return round(value * factor) / factor;
8}
9 
10int main()
11{
12 double x = 3.14159265;
13 
14 printf("printf only : %.2f (value unchanged)\n", x);
15 printf("roundTo 2 : %.8f\n", roundTo(x, 2));
16 printf("roundTo 4 : %.8f\n", roundTo(x, 4));
17 return 0;
18}
Output
printf only : 3.14  (value unchanged)
roundTo 2   : 3.14000000
roundTo 4   : 3.14160000

Guard Against Invalid Input

sqrt of a negative and log of zero produce nan and -inf. Check before you call:

Example09
CCode Cell
1#include <stdio.h>
2#include <math.h>
3 
4int main()
5{
6 double n = -16.0;
7 
8 printf("Unchecked sqrt(-16) = %f\n", sqrt(n));
9 
10 if (n >= 0)
11 printf("Checked sqrt = %.2f\n", sqrt(n));
12 else
13 printf("Checked sqrt = cannot take root of a negative\n");
14 
15 printf("log(0) = %f\n", log(0.0));
16 return 0;
17}
Output
Unchecked sqrt(-16) = -nan
Checked   sqrt      = cannot take root of a negative
log(0)              = -inf

Common Mistakes

  • Forgetting -lmundefined reference to 'sqrt' at link time.
  • Passing degrees to sin — the functions take radians.
  • Using abs on a double — truncates before taking the absolute value. Use fabs.
  • Expecting log to be base 10 — it is base e. Use log10.
  • pow(2, 3) for integers — returns a double and is slower than 2 * 2 * 2.
  • Comparing floats with ==sqrt(2) * sqrt(2) == 2 is false. Compare within a tolerance.
Trainer's Note: never test floating-point results for exact equality. sqrt(2.0) * sqrt(2.0) comes out as 2.0000000000000004. Write fabs(a - b) < 1e-9 instead of a == b.
📝 Key Takeaways
  • Include <math.h> to use any of these functions.
  • On Linux and macOS, compile with gcc file.c -lm.
  • Most math.h functions take and return double.
  • Use fabs for floating-point absolute value, abs for int.
  • Trigonometric functions work in radians, not degrees.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4