Skip to content

Arduino - Math Library

The Arduino environment, being built on C++, includes the standard C Math Library (math.h), which provides a rich set of functions for performing floating-point mathematics. This is essential for tasks involving sensor data processing, animation, robotics, and more.

To use these functions, you typically include the library at the top of your sketch:

#include <math.h>

While this is often included by default in the Arduino toolchain, explicitly including it is a good practice for clarity and portability.

Understanding Floats and Doubles on Arduino

Section titled “Understanding Floats and Doubles on Arduino”

A crucial point for Arduino developers: on many classic Arduino boards (like the Uno, Nano, Mega, based on the AVR architecture), the double data type is implemented as a 4-byte floating-point number, identical to float. There is no extra precision. On more powerful, 32-bit boards (like the Arduino Due, Zero, or ESP32-based boards), double provides 8-byte, double-precision floating-point numbers. Always be aware of your target board’s capabilities when dealing with high-precision calculations.

The math.h library defines several useful mathematical constants. Here are the most important ones:

ConstantApproximate ValueDescription
M_PI3.14159265The constant Pi (π).
M_E2.71828182The constant e, the base of the natural logarithm.
M_SQRT21.41421356The square root of 2.
M_LN20.69314718The natural logarithm of 2.
M_LN102.30258509The natural logarithm of 10.

Below is a curated list of the most frequently used functions from the library. Note that trigonometric functions always operate in radians, not degrees.

Function SignatureDescription
double sin(double x)Calculates the sine of x, where x is in radians.
double cos(double x)Calculates the cosine of x, where x is in radians.
double tan(double x)Calculates the tangent of x, where x is in radians.
double asin(double x)Calculates the arc sine (inverse sine) of x. Returns a value in radians between -π/2 and π/2. x must be between -1 and 1.
double acos(double x)Calculates the arc cosine (inverse cosine) of x. Returns a value in radians between 0 and π. x must be between -1 and 1.
double atan2(double y, double x)Calculates the arc tangent of y/x, using the signs of both arguments to determine the correct quadrant. Returns a value in radians between -π and π. This is generally safer than atan(y/x).
double pow(double base, double exponent)Computes base raised to the power of exponent.
double sqrt(double x)Computes the non-negative square root of x.
double cbrt(double x)Computes the cube root of x.
double exp(double x)Computes e raised to the power of x (e^x).
double log(double x)Computes the natural logarithm (base e) of x.
double log10(double x)Computes the common logarithm (base 10) of x.
double fabs(double x)Computes the absolute value of a floating-point number x.
double floor(double x)Rounds x downward to the nearest integer (returns a float).
double ceil(double x)Rounds x upward to the nearest integer (returns a float).
double round(double x)Rounds x to the nearest integer, rounding halfway cases away from zero.
double fmod(double x, double y)Computes the floating-point remainder of x / y.
double hypot(double x, double y)Calculates sqrt(x*x + y*y) robustly, avoiding intermediate overflow or underflow.
int isnan(double x)Returns a non-zero value if x is Not-a-Number (NaN), otherwise 0.
int isinf(double x)Returns 1 if x is positive infinity, -1 for negative infinity, and 0 otherwise.

Note on square(): The Arduino core also provides a square(x) macro, which simply returns x * x. While convenient, it is not part of the standard C math library and can have unexpected side effects due to its macro implementation. Using pow(x, 2) or x * x directly is often safer and clearer.

This example demonstrates several key math functions. It converts an angle from degrees to radians, calculates trigonometric values, and shows the use of pow and sqrt.

// Include the math library for clarity
#include <math.h>
// Use 'const' for values that do not change.
const float angleDegrees = 60.0;
void setup() {
Serial.begin(9600);
while (!Serial); // Wait for Serial monitor to connect
Serial.println("--- Arduino Math Library Demo ---");
// --- Trigonometry ---
// Trig functions require angles in radians. Let's convert.
float angleRadians = angleDegrees * (M_PI / 180.0);
Serial.print("Angle (degrees): ");
Serial.println(angleDegrees);
Serial.print("Angle (radians): ");
Serial.println(angleRadians, 4); // Print with 4 decimal places
float sinValue = sin(angleRadians);
float cosValue = cos(angleRadians);
Serial.print("Sine of angle: ");
Serial.println(sinValue, 4);
Serial.print("Cosine of angle: ");
Serial.println(cosValue, 4);
// --- Powers and Roots ---
float base = 4.0;
float exponent = 3.0; // 4^3
float powerResult = pow(base, exponent);
Serial.print(base);
Serial.print(" raised to the power of ");
Serial.print(exponent);
Serial.print(" is: ");
Serial.println(powerResult);
float numberToRoot = 81.0;
float sqrtResult = sqrt(numberToRoot);
Serial.print("The square root of ");
Serial.print(numberToRoot);
Serial.print(" is: ");
Serial.println(sqrtResult);
// --- Rounding ---
float valueToRound = -3.7;
Serial.print("Rounding ");
Serial.println(valueToRound);
Serial.print(" floor(): ");
Serial.println(floor(valueToRound));
Serial.print(" ceil(): ");
Serial.println(ceil(valueToRound));
Serial.print(" round(): ");
Serial.println(round(valueToRound));
}
void loop() {
// Nothing to do here for this example
}
--- Arduino Math Library Demo ---
Angle (degrees): 60.00
Angle (radians): 1.0472
Sine of angle: 0.8660
Cosine of angle: 0.5000
4.00 raised to the power of 3.00 is: 64.00
The square root of 81.00 is: 9.00
Rounding -3.70
floor(): -4.00
ceil(): -3.00
round(): -4.00
  • Radians, not Degrees: This is the most common mistake. Always convert degrees to radians (radians = degrees * M_PI / 180.0) before using sin(), cos(), tan(), etc.
  • Domain Errors: Functions like acos(x) and asin(x) are only defined for x between -1 and 1. log(x) is only defined for x > 0. Providing an out-of-range value will result in NaN (Not a Number). Use isnan() to check for this error.
  • Performance: Floating-point math is significantly slower than integer math on most Arduinos. If you need speed, try to re-frame your problem using integers where possible.
  • Precision: float has about 6-7 decimal digits of precision. If your calculations are accumulating small errors, the final result can be inaccurate. Be mindful of this limitation.