<cmath>
Standard C++ header providing mathematical functions for floating-point arithmetic, rounding, classification, and error handling.
<cmath>since C++98The <cmath> header provides the C++ standard mathematical function library β a superset of C's <math.h> β placing all names in namespace std and adding overloads for float, double, and long double argument types.
Overview
<cmath> is C++'s primary header for floating-point mathematics. It wraps and extends the C <math.h> library, organising its contents into several functional groups:
- Basic:
abs,fabs,fmod,remainder,remquo,fma,fmax,fmin,fdim - Exponential / logarithmic:
exp,exp2,expm1,log,log2,log10,log1p - Power / root:
pow,sqrt,cbrt,hypot - Trigonometric:
sin,cos,tan,asin,acos,atan,atan2 - Hyperbolic:
sinh,cosh,tanh,asinh,acosh,atanh - Rounding:
ceil,floor,trunc,round,lround,llround,nearbyint,rint,lrint,llrint - Floating-point manipulation:
frexp,ldexp,modf,scalbn,scalbln,ilogb,logb,nextafter,nexttoward,copysign - Classification / comparison:
fpclassify,isfinite,isinf,isnan,isnormal,signbit,isgreater,isless,isunordered
Prior to C++11 the header provided only double overloads; C++11 added float and long double overloads for every function, plus the classification macros were promoted to proper function templates. Several functions gained constexpr qualification in C++20 and C++23 (see individual notes below).
Relationship to <math.h>
Including <cmath> is preferred over <math.h> in C++ code. Both ultimately expose the same functions, but <cmath> guarantees placement in namespace std, eliminating naming collisions and enabling argument-dependent lookup. The <math.h> form additionally injects names into the global namespace β a behaviour that is implementation-defined for <cmath> and not to be relied upon.
Syntax
#include <cmath>
// All functions live in namespace std
double r = std::sqrt(2.0);
float s = std::sqrtf(2.0f); // C-style suffix form β still valid
float t = std::sqrt(2.0f); // C++11: preferred float overloadSince C++11 every function is overloaded for float, double, and long double. When an integer argument is passed the result type is double:
double x = std::sqrt(4); // C++11: int promoted to double β 2.0Examples
Geometry: distance and angle
#include <cmath>
#include <numbers> // C++20: std::numbers::pi
#include <print> // C++23: std::println
struct Vec2 { double x, y; };
double magnitude(Vec2 v) {
return std::hypot(v.x, v.y); // avoids intermediate overflow
}
double angle_deg(Vec2 v) {
double rad = std::atan2(v.y, v.x);
return rad * (180.0 / std::numbers::pi); // C++20
}
int main() {
Vec2 v{3.0, 4.0};
std::println("magnitude: {}", magnitude(v)); // 5.0
std::println("angle: {}Β°", angle_deg(v)); // 53.13...
}std::hypot computes β(xΒ²+yΒ²) without the overflow risk of writing std::sqrt(x*x + y*y). Since C++17, a three-argument form std::hypot(x, y, z) computes the 3-D Euclidean norm.
Floating-point classification
#include <cmath>
#include <limits>
bool safe_log(double x, double& result) {
if (!std::isfinite(x) || x <= 0.0)
return false;
result = std::log(x);
return true;
}
void inspect(double v) {
switch (std::fpclassify(v)) {
case FP_INFINITE: /* handle inf */ break;
case FP_NAN: /* handle NaN */ break;
case FP_SUBNORMAL: /* handle denormal */ break;
case FP_ZERO: /* handle zero */ break;
case FP_NORMAL: /* ordinary value */ break;
}
}std::isnan, std::isinf, and std::isfinite (C++11 function templates) replace the isnan / isinf macros from C. Prefer the std:: versions; the global-namespace macros may not exist in all translation units.
Rounding modes
#include <cmath>
// C++11: all rounding variants exist
double v = 2.7;
std::floor(v); // 2.0 β toward -β
std::ceil(v); // 3.0 β toward +β
std::trunc(v); // 2.0 β toward zero (C++11)
std::round(v); // 3.0 β nearest, halfway away from zero
std::nearbyint(v); // 3.0 β nearest, respects current rounding mode, no FE_INEXACT
std::rint(v); // 3.0 β nearest, respects current rounding mode, raises FE_INEXACTstd::nearbyint and std::rint differ only in whether they raise the FE_INEXACT floating-point exception. If you need to suppress that exception (e.g., in hot inner loops where <cfenv> error tracking is active), prefer std::nearbyint.
Fused multiply-add
#include <cmath>
// C++11: std::fma computes (x * y) + z with a single rounding step
double dot(double ax, double bx, double ay, double by) {
return std::fma(ax, bx, ay * by);
}std::fma (C++11) is exact to within one ULP when the hardware provides a native FMA instruction. On platforms without native FMA it is emulated but still produces the correct mathematical result. Use it whenever intermediate rounding in x*y + z would be a problem β polynomial evaluation being the classic case.
Error handling
#include <cmath>
#include <cerrno>
#include <cstring>
double safe_sqrt(double x) {
errno = 0;
double r = std::sqrt(x);
if (errno == EDOM)
throw std::domain_error("sqrt of negative");
return r;
}Error reporting from <cmath> is controlled by math_errhandling (defined in <cmath>, not in namespace std). It holds a bitwise OR of:
| Constant | Meaning |
|---|---|
MATH_ERRNO | Errors reported via errno |
MATH_ERREXCEPT | Errors raised as floating-point exceptions (<cfenv>) |
At least one of the two bits is set by any conforming implementation. On most Linux/glibc targets both are set; on MSVC only MATH_ERRNO is. Do not assume a specific combination.
Best Practices
Prefer std::hypot over manual Pythagorean sums. Writing std::sqrt(x*x + y*y) overflows when x or y exceeds βDBL_MAX β 1.3Γ10ΒΉβ΅β΄. std::hypot is required by the standard to avoid spurious overflow and underflow.
Use std::fma for compensated arithmetic. When building polynomial evaluators (Horner's method) or compensated summations, std::fma eliminates the intermediate rounding step and typically maps to a single hardware instruction on x86-64 (VFMADD), ARM (FMADD), and POWER (fmadd).
Classify before computing. Always guard std::log, std::sqrt, std::asin, and similar domain-restricted functions with std::isfinite and range checks on untrusted input. Passing a negative value to std::sqrt sets errno = EDOM and returns NaN β it does not throw.
Match argument and return types. Mixing float arguments with a double result variable triggers an implicit widening conversion that silently defeats the purpose of using float for performance. Assign to the same type: float r = std::sqrtf(x) or float r = std::sqrt(x) (C++11 overload).
Do not use using namespace std; to shorten math calls in headers. Importing the entire std namespace in a header drags in hundreds of names and is a well-known source of ODR violations.
Common Pitfalls
std::abs vs std::fabs for floating-point. std::abs with a double argument is declared in <cmath> since C++11. Before C++11, std::abs for floating-point was only guaranteed by including <cstdlib> (which provided the integer version) or <cmath>. With C++11 or later, prefer std::abs with <cmath> included. Including only <cstdlib> and calling std::abs(3.7) silently truncates to integer abs on older compilers.
NaN propagation is asymmetric for min/max. std::fmin(NaN, 1.0) returns 1.0 (NaN is treated as missing data per IEEE 754), whereas std::min(NaN, 1.0) has unspecified behaviour and frequently returns the wrong value. Use std::fmin/std::fmax when one operand may be NaN.
std::pow(base, 2) is not an optimisation. Many compilers do not special-case integer exponents in std::pow; the call is typically slower and less accurate than base * base. Write the multiplication explicitly or use std::fma(base, base, 0.0).
math_errhandling is not in namespace std. Unlike nearly everything else in <cmath>, math_errhandling, MATH_ERRNO, and MATH_ERREXCEPT are macros defined at global scope. Do not write std::math_errhandling.
Integer literals produce double. std::sqrt(2) is valid C++11 (integer argument overload resolves to double), but std::sqrt(2.f) selects the float overload. Ensure literal suffixes match the intended precision.
See Also
<numbers>β C++20 mathematical constants (std::numbers::pi,std::numbers::e, β¦)<cfenv>β floating-point environment control (rounding mode, exception flags)<complex>β complex-number overloads of most<cmath>functions<numeric>βstd::gcd,std::lcm,std::midpoint,std::lerp(C++17/20)<valarray>β element-wise application of math functions to arrays