Question
I want to use the value of pi together with trigonometric functions in a C++ program. I can access trigonometric functions by including math.h, but I cannot find a built-in definition for pi in that header.
How can I use pi in C++ without manually defining it myself?
Short Answer
By the end of this page, you will understand how C++ provides trigonometric functions, why pi is not always available as a simple global constant, and the recommended ways to access it in modern C++. You will also see practical examples using std::sin, std::cos, and std::numbers::pi.
Concept
C++ provides many mathematical functions such as sin, cos, tan, and sqrt, but mathematical constants like pi have historically been handled differently.
The important idea is this:
cmathgives you math functions- Pi is a constant, not a function
- Older C++ code often used non-standard macros like
M_PI - Modern C++ provides a standard way:
std::numbers::pi
Why this matters
If you are writing code that uses angles, circles, graphics, simulations, or physics, you will need pi frequently. Using a reliable source for pi helps make your code:
- more readable
- more portable
- more precise
- more standard-compliant
The old situation
In C and older C++ code, developers often included:
#include <math.h>
and hoped to get M_PI. The problem is that M_PI is not part of the C++ standard. Some compilers provide it, some do not, and some require extra settings.
The modern C++ solution
Since C++20, the standard library includes mathematical constants in the <numbers> header:
#include <numbers>
You can then use:
std::numbers::pi
There are also typed versions such as:
std::numbers::pi_v<double>
std::numbers::pi_v<float>
std::numbers::pi_v<long double>
This is the best standard solution in modern C++.
Use cmath instead of math.h
In C++, prefer:
#include <cmath>
instead of:
#include <math.h>
<cmath> places functions in the std namespace, so you typically write:
std::sin(...)
std::cos(...)
Mental Model
Think of <cmath> as a toolbox of math operations and <numbers> as a reference sheet of math constants.
- Need to calculate something? Use the toolbox:
std::sin,std::cos,std::sqrt - Need a known fixed value? Use the reference sheet:
std::numbers::pi
Pi is like a universal measuring reference. You do not "compute" it each time you need it. You simply look it up from a trusted source.
Syntax and Examples
In modern C++, the recommended approach is:
#include <iostream>
#include <cmath>
#include <numbers>
int main() {
double radius = 5.0;
double area = std::numbers::pi * radius * radius;
std::cout << "Area: " << area << '\n';
std::cout << "sin(pi / 2): " << std::sin(std::numbers::pi / 2) << '\n';
}
What this does
<cmath>providesstd::sin<numbers>providesstd::numbers::pistd::numbers::pi / 2represents 90 degrees in radians
Typed pi constants
If you want a specific type, use pi_v<T>:
#include <iostream>
#include <numbers>
int main() {
float pi_f = std::numbers::pi_v<float>;
double pi_d = std::numbers::pi_v<double>;
long double pi_ld = std::numbers::pi_v<long double>;
std::cout << pi_f << '\n';
std::cout << pi_d << '\n';
std::cout << pi_ld << '\n';
}
If you are using pre-C++20
If your compiler does not support <numbers>, you may need to define your own constant:
#include <iostream>
#include <cmath>
int main() {
constexpr double pi = 3.14159265358979323846;
std::cout << std::sin(pi / 2) << '\n';
}
This is often better than relying on M_PI, because it is explicit and portable.
Non-standard M_PI
Some systems support:
#include <cmath>
#include <iostream>
int main() {
std::cout << M_PI << '\n';
}
But this is not guaranteed to work everywhere, so avoid depending on it in portable C++ code.
Step by Step Execution
Consider this example:
#include <iostream>
#include <cmath>
#include <numbers>
int main() {
double angle = std::numbers::pi / 2;
double result = std::sin(angle);
std::cout << result << '\n';
}
Step by step
#include <iostream>lets the program print output.#include <cmath>gives access to math functions likestd::sin.#include <numbers>gives access tostd::numbers::pi.double angle = std::numbers::pi / 2;- This stores half of pi.
- Half of pi radians is 90 degrees.
double result = std::sin(angle);std::sinexpects the angle in radians, not degrees.sin(pi / 2)is mathematically1.
std::cout << result << '\n';- Prints the result.
Expected output
1
In practice, floating-point output may sometimes look like this:
0.999999
That is normal due to floating-point precision.
Real World Use Cases
Pi appears in many kinds of software:
Graphics and game development
- rotating objects using radians
- drawing circles and arcs
- computing wave motion
double angle = std::numbers::pi / 4;
double x = std::cos(angle);
double y = std::sin(angle);
Scientific and engineering software
- orbital calculations
- signal processing
- geometry formulas
- simulations
Data visualization
- polar charts
- circular gauges
- radar plots
Robotics and embedded systems
- wheel rotation calculations
- motor angle conversion
- sensor orientation math
Education and scripting tools
- math utilities
- unit converters
- trigonometry demos
Real Codebase Usage
In real projects, developers usually combine mathematical constants with a few common patterns.
1. Prefer standard headers and namespaces
Use:
#include <cmath>
#include <numbers>
and call functions explicitly:
std::sin(value)
std::cos(value)
std::numbers::pi
This avoids ambiguity and makes code easier to read.
2. Convert degrees to radians
Many real applications receive degrees from users, files, or APIs, but C++ trig functions use radians.
#include <numbers>
double degrees_to_radians(double degrees) {
return degrees * std::numbers::pi / 180.0;
}
This helper function is common in codebases.
3. Use constexpr for reusable constants
If you are not on C++20, teams often define a local constant:
constexpr double pi = 3.14159265358979323846;
constexpr allows compile-time evaluation and makes the value clearly intentional.
4. Guard against wrong units
A very common source of bugs is mixing degrees and radians. Developers often name variables clearly:
double angle_radians = std::numbers::pi / 3;
double angle_degrees = 60.0;
5. Wrap formulas in small functions
Instead of repeating formulas everywhere:
double circle_area(double radius) {
return std::numbers::pi * radius * radius;
}
This improves reuse and reduces mistakes.
Common Mistakes
1. Using math.h instead of cmath
Less idiomatic C++
#include <math.h>
Better C++
#include <cmath>
In C++, prefer the standard C++ header.
2. Expecting M_PI to always exist
Broken assumption:
#include <cmath>
#include <iostream>
int main() {
std::cout << M_PI << '\n';
}
This may fail on some compilers because M_PI is non-standard.
Use:
std::numbers::pi
or define your own constexpr constant if needed.
3. Forgetting the std:: namespace
Broken code:
double x = sin(3.14 / 2);
Preferred:
double x = std::sin(std::numbers::pi / 2);
4. Passing degrees directly to trig functions
Broken logic:
std::cout << std::sin(90) << '\n';
This treats 90 as 90 radians, not 90 degrees.
Correct approach:
double radians = 90.0 * std::numbers::pi / 180.0;
std::cout << std::sin(radians) << '\n';
5. Using low-precision values of pi
Less accurate:
constexpr double pi = 3.14;
Better:
constexpr double pi = 3.14159265358979323846;
6. Comparing floating-point results for exact equality
Risky:
if (std::sin(std::numbers::pi / 2) == 1.0) {
// may not always behave as expected
}
Better:
#include <cmath>
if (std::abs(std::sin(std::numbers::pi / 2) - 1.0) < 1e-9) {
// close enough
}
Comparisons
| Option | Standard? | Recommended? | Notes |
|---|---|---|---|
std::numbers::pi | Yes, C++20+ | Yes | Best modern standard solution |
std::numbers::pi_v<double> | Yes, C++20+ | Yes | Useful when you want a specific type |
M_PI | No | No | Common on some platforms, but non-standard |
constexpr double pi = ... | Yes | Yes for pre-C++20 | Portable fallback |
<cmath> vs <math.h>
| Header | Language style | Namespace behavior | Recommended in C++? |
|---|---|---|---|
<cmath> | C++ | Usually in std | Yes |
<math.h> | C style | Older style/global compatibility | No |
Pi constant vs calculating with literals
| Approach | Example | Good choice? |
|---|---|---|
| Named constant | std::numbers::pi | Yes |
| Manual literal in many places | 3.14159265358979323846 repeated everywhere | No |
| Short approximation | 3.14 | Usually no |
Cheat Sheet
// Modern C++
#include <cmath>
#include <numbers>
double x = std::numbers::pi;
double y = std::sin(std::numbers::pi / 2);
// Typed versions
float pf = std::numbers::pi_v<float>;
double pd = std::numbers::pi_v<double>;
long double pld = std::numbers::pi_v<long double>;
// Pre-C++20 fallback
constexpr double pi = 3.14159265358979323846;
Quick rules
- Prefer
<cmath>over<math.h> - Prefer
std::numbers::piin C++20+ - Do not rely on
M_PIfor portable code std::sin,std::cos, andstd::tanuse radians- Convert degrees to radians with:
degrees * pi / 180.0
Common formulas
// Circle area
area = pi * r * r;
// Circle circumference
circumference = 2 * pi * r;
// Degrees to radians
radians = degrees * pi / 180.0;
// Radians to degrees
degrees = radians * 180.0 / pi;
FAQ
Why does C++ not always provide M_PI?
M_PI is not part of the C++ standard. Some compilers or libraries provide it as an extension, but portable C++ code should not depend on it.
What is the standard way to get pi in modern C++?
Use std::numbers::pi from the <numbers> header in C++20 and later.
Should I use <math.h> or <cmath> in C++?
Use <cmath>. It is the C++ version of the math header and works better with the std namespace.
Do C++ trigonometric functions use degrees or radians?
They use radians. If you have degrees, convert them first.
What if my compiler does not support <numbers>?
Use a local constexpr constant such as:
constexpr double pi = 3.14159265358979323846;
Is std::numbers::pi better than writing 3.14159265358979323846 directly?
Yes. It is clearer, standard, and avoids repeating the literal throughout your code.
Can I use float or long double versions of pi?
Yes. Use std::numbers::pi_v<float> or std::numbers::pi_v<long double> when you want a specific type.
Mini Project
Description
Build a small C++ program that calculates circle properties and evaluates a trigonometric value from a degree input. This project demonstrates how to use pi correctly, how to convert degrees to radians, and how to call standard math functions in practical code.
Goal
Create a program that reads a radius and an angle in degrees, then prints the circle area, circumference, and the sine of the angle.
Requirements
- Read a circle radius from the user.
- Read an angle in degrees from the user.
- Use a standard pi source where available.
- Convert the degree input to radians before calling
std::sin. - Print the area, circumference, and sine result clearly.
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.