653

I want to use the PI constant and trigonometric functions in some C++ program. I get the trigonometric functions with include <math.h>. However, there doesn't seem to be a definition for PI in this header file.

How can I get PI without defining it manually?

4
  • 3
    @tiwo, are you asking what's the difference between 3.14, 3.141592 and atan(1) * 4? Commented Sep 6, 2012 at 16:09
  • 49
    As a side note, cmath should be used in C++ instead of math.h, which is for C. Commented Nov 20, 2014 at 17:13
  • 5
    Loosely related: see cise.ufl.edu/~manuel/obfuscate/pi.c on how to calculate value of PI directly from definition. Commented Jul 26, 2016 at 18:20
  • 16
    It has arrived in C++20! stackoverflow.com/a/57285400/895245 Commented Jul 31, 2019 at 8:02

24 Answers 24

711

On some (especially older) platforms (see the comments below) you might need to

#define _USE_MATH_DEFINES 

and then include the necessary header file:

#include <math.h> 

and the value of pi can be accessed via:

M_PI 

In my math.h (2014) it is defined as:

# define M_PI 3.14159265358979323846 /* pi */ 

but check your math.h for more. An extract from the "old" math.h (in 2009):

/* Define _USE_MATH_DEFINES before including math.h to expose these macro * definitions for common math constants. These are placed under an #ifdef * since these commonly-defined names are not part of the C/C++ standards. */ 

However:

  1. on newer platforms (at least on my 64 bit Ubuntu 14.04) I do not need to define the _USE_MATH_DEFINES

  2. On (recent) Linux platforms there are long double values too provided as a GNU Extension:

    # define M_PIl 3.141592653589793238462643383279502884L /* pi */ 
Sign up to request clarification or add additional context in comments.

9 Comments

#define _USE_MATH_DEFINES followed by #include <math.h> defines M_PI in visual c++. Thanks.
Works with cygwin headers as well.
You can always include cmath instead of math.h.
Even after defining _USE_MATH_DEFINES if GCC complains that's because __STRICT_ANSI__ is defined (perhaps you passed -pedantic or -std=c++11) which disallows M_PI to be defined, hence undefine it with -D__STRICT_ANSI__. When defining it yourself, since it's C++, instead of a macro you should constexpr auto M_PI = 3.14159265358979323846;.
As of 2018, The answer should definetely be updated to use <cmath> instead of <math.h>
|
237

C++20 std::numbers::pi

At last, it has arrived: http://eel.is/c++draft/numbers

main.cpp

#include <cfloat> #include <cstdio> #include <numbers> // std::numbers #include <iomanip> #include <iostream> int main() { std::cout << std::fixed << std::setprecision(20); std::cout << "float " << std::numbers::pi_v<float> << std::endl; std::cout << "double " << std::numbers::pi << std::endl; std::cout << "long double " << std::numbers::pi_v<long double> << std::endl; std::cout << "exact " << "3.141592653589793238462643383279502884197169399375105820974944" << std::endl; printf("\nhex \n"); printf("float %A\n", std::numbers::pi_v<float>); printf("double %A\n", std::numbers::pi); // Doesn't print the result in a very comparable way because %LA // randomly has a different hex grouping than %A. // 0XC.90FDAA22168C235P-2 printf("long double %LA\n", std::numbers::pi_v<long double> - (long double)std::numbers::pi); printf("exact %s\n", "0x1.921FB54442D18469898CC51701B839A252049C1114CF98E803"); printf("\nLDBL_MANT_DIG=%d\n", LDBL_MANT_DIG); } 

Compile and run:

g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o main.out main.cpp ./main.out 

Output:

float 3.14159274101257324219 double 3.14159265358979311600 long double 3.14159265358979323851 exact 3.141592653589793238462643383279502884197169399375105820974944 hex float 0X1.921FB6P+1 double 0X1.921FB54442D18P+1 long double 0X8.D4P-56 exact 0x1.921FB54442D18469898CC51701B839A252049C1114CF98E803 LDBL_MANT_DIG=64 

It is a bit easier to make sense of the precision of the hex output, remembering that in IEEE 754:

  • 23 bit significand
  • 52 bit significand
  • 112 bit significand

Tested on Ubuntu 20.04 amd64, GCC 10.2.0

The "exact" result was calculated with:

echo "scale=60; 4*a(1)" | BC_LINE_LENGTH=0 bc -l 

as per: How can I calculate pi using Bash command and the hex one was obtained with:

echo "scale=60; obase=16; 4*a(1)/2" | BC_LINE_LENGTH=0 bc -l 

The division by 2 is to align bc hex output to C hex output bits so we can compare them nicely.

The accepted proposal describes:

5.0. “Headers” [headers] In the table [tab:cpp.library.headers], a new <math> header needs to be added.

[...]

namespace std { namespace math { template<typename T > inline constexpr T pi_v = unspecified; inline constexpr double pi = pi_v<double>; 

There is also a std::numbers::e of course :-) How to calculate Euler constant or Euler powered in C++?

These constants use the C++14 variable template feature: C++14 Variable Templates: what is their purpose? Any usage example?

In earlier versions of the draft, the constant was under std::math::pi: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdf

8 Comments

I don't understand why the long double precision pi has only two more digits of accuracy than the double precision pi. That suggests that it's hardly worth using long double.
@Anachronist good observation, I'm not too sure why this is the case, let me know if anyone figures it out, I'm lazy to think now :) Related: stackoverflow.com/questions/15176290/…
Why is the float value so far off? 3.xxxxxx74101257324219 ? It should be 3.14159265f
@Anachronist It could be a sign that on g++10, on your machine (like on mine), the long doubles are implemented as 80-bits extended precision, not quadruple precision.
@CiroSantilliOurBigBook.com Sorry, I initially missed the code comment. I am confident your print library has a bug (fails %La) - I have seen it before. (make certain you are using latest version of the library) printf("long double %a\n", (double) (std::numbers::pi_v<long double> - 0X1.921FB54442D00P+1)); (corrected comment) will likely print correctly the expected least significant digits 1846a (in a shifted manner), for a total of about 64-bit significance.
|
196

Pi can be calculated as atan(1)*4. You could calculate the value this way and cache it.

21 Comments

For c++11 users: constexpr double pi() { return std::atan(1)*4; }
-1: Works only if atan(1)*4 == 3.141592653589793238462643383279502884 (roughly speaking). I wouldn't bet on it. Be normal and use a raw literal to define the constant. Why lose precision when you don't need to?
One can avoid the multiplication operation with atan2(0, -1);.
@matiu atan is not constexpr.
Try acos(-1) instead, no need for atan2.
|
137

Get it from the FPU unit on chip instead:

double get_PI() { double pi; __asm { fldpi fstp pi } return pi; } double PI = get_PI(); 

5 Comments

:-) probably not that platform independent, but a nice additional exotic solution!
i love how you though out of the box here ;)
I love this answer. It is particularly useful when targeting older x86 platforms which is a small fad as of late where the optimizing compilers aren't as terribly involved as modern ones. Thanks for this Henrik!
Having to load PI at runtime? Why...
@user16217248-OnStrike because you don't necessarily compile on the same machine on which you run. Perhaps the runtime machine has a tastier pi.
125

You could also use boost, which defines important math constants with maximum accuracy for the requested type (i.e. float vs double).

const double pi = boost::math::constants::pi<double>(); 

Check out the boost documentation for more examples.

13 Comments

Boost: Boosting the already unnecessary complexity of C++ since 1999!
Catchy and partly true. On the other hand boost can be phenomenally useful at times...
@DanMoulding: Uhm. Is C the only other language you know? Because all other languages I know, except C, have a standard library which is magnitudes bigger than C++' (e.g. Python, Haskell, C#, PHP, Delphi, Erlang, Java, ......). From personal experience, that elitist not gonna use libs-opinion is a pest and probably the number one reason for bad software written in C++.
@Gracchus: Yup. C++ without libraries (or without the new C++11 libraries) is, as much as I like that language and as much as I would like to code everything myself, not very productive.
I believe he said complexity not size. Presumably referring to a) the 3 nested namespaces, and b) defining pi as a templated function rather than just a normal constant.
|
57

I would recommend just typing in pi to the precision you need. This would add no calculation time to your execution, and it would be portable without using any headers or #defines. Calculating acos or atan is always more expensive than using a precalculated value.

const double PI =3.141592653589793238463; const float PI_F=3.14159265358979f; 

9 Comments

This is a great example why we should not take this approach, we people make mistakes, rounding, copy&pasting, etc. I think using M_PI is the right approach.
If one is doing this in C++11, make the const a constexpr.
@nacho4d I too prefer M_PI if it's available, but not all systems are POSIX compliant. I think this approach is better than the 4*atan(1) method for the cases where M_PI is not available.
"Calculating acos or atan is always more expensive" is not true. Any modern optimizing compiler knows all about standard math functions and can constant-propagate through them. See e.g. godbolt.org/g/BvdJyr
@Nemo, Counter example: godbolt.org/g/DsAern As has been said elsewhere, it appears only GCC does this currently and that's likely because it has declared the basic math functions as constexpr.
|
52

Rather than writing

#define _USE_MATH_DEFINES 

I would recommend using -D_USE_MATH_DEFINES or /D_USE_MATH_DEFINES depending on your compiler.

This way you are assured that even in the event of someone including the header before you do (and without the #define) you will still have the constants instead of an obscure compiler error that you will take ages to track down.

4 Comments

Good tip. If "you" are a compilation unit then of course you can ensure the macro is defined before anything is included. But if "you" are a header file, it's out of your control.
In fact even if "you" are a compilation unit... depending on the ordering of the headers is a the shortest path toward maintenance nightmare...
You don't have to depend on the ordering of the headers, though. It doesn't matter whether headers include each other, provided that you do the #define before you #include anything at all (at least, assuming that nothing #undefs it). Same applies to NDEBUG.
The very common issue in a project is that if you're compiling with Visual Studio for example you don't know in which order the compiler is going to go through your files so if you use <cmath> in different places it becomes a big pain (especially if it is included by another library you are including). It would have been much better if they put that part outside of the header guards but well can't do much about that now. The compiler directive works pretty well indeed.
42

Since the official standard library doesn't define a constant PI you would have to define it yourself. So the answer to your question "How can I get PI without defining it manually?" is "You don't -- or you rely on some compiler-specific extensions.". If you're not concerned about portability you could check your compiler's manual for this.

C++ allows you to write

const double PI = std::atan(1.0)*4; 

but the initialization of this constant is not guaranteed to be static. The G++ compiler however handles those math functions as intrinsics and is able to compute this constant expression at compile-time.

9 Comments

I usually use acos(-1), as you say, they are compile-time evaluated. When I tested M_PI, acos(-1) and atan(1)*4, I got identical values.
The traditional way is to use 4*atan(1.): atan is easy to implement and multiplying by 4 is an exact operation. Of course, modern compilers fold (aim to fold) all constants with the required precision, and it's perfectly reasonable to use acos(-1) or even std::abs(std::arg(std::complex<double>(-1.,0.))) which is the inverse of Euler's formula and thus more aesthetically pleasing than it seems (I've added abs because I don't remember how the complex plane is cut or if that's defined at all).
Just so no one accidentally thinks you are serious (again-_-'). This is a terrible solution. The atan implementation is not defined by the standard meaning its implementation and possibly hw dependent. This means that the numerics can be terrible, meaning you may well be better off using 3.14 in general. Further its quite possibly slow, even for the special cases.
4*atan(1) loses 2 digits of precision over the 1 in M_PI_2 / 2, doesn't it? And I recommend against storing directly in your data type. Same reason as above: "For floating point multiplication: FP multipliers use internally double the width of the operands to generate an intermediate result, which equals the real result within an infinite precision, and then round it to the target precision."
@JohnP: Would you be happier with ldexp(atan(1.0), 2) ? As Micah noted, multiplication by 4 is an exact operation (as indeed is multiplication by any power of 2)
|
42

From the POSIX specification of <math.h>:

The <math.h> header shall provide for the following constants. The values are of type double and are accurate within the precision of the double type.

  • M_PI Value of 𝜋
  • M_PI_2 Value of 𝜋/2
  • M_PI_4 Value of 𝜋/4
  • M_1_PI Value of 1/𝜋
  • M_2_PI Value of 2/𝜋
  • M_2_SQRTPI Value of 2/√𝜋

Comments

30

Standard C++ doesn't have a constant for PI.

Many C++ compilers define M_PI in cmath (or in math.h for C) as a non-standard extension. You may have to #define _USE_MATH_DEFINES before you can see it.

1 Comment

Good news, everybody! It does now / it's about to. eel.is/c++draft/numbers -- I don't love all their choices but as a concept (no pun intended) it's long overdue.
21

I would do

template<typename T> T const pi = std::acos(-T(1)); 

or

template<typename T> T const pi = std::arg(-std::log(T(2))); 

I would not typing in π to the precision you need. What is that even supposed to mean? The precision you need is the precision of T, but we know nothing about T.

You might say: What are you talking about? T will be float, double or long double. So, just type in the precision of long double, i.e.

template<typename T> T const pi = static_cast<T>(/* long double precision π */); 

But do you really know that there won't be a new floating point type in the standard in the future with an even higher precision than long double? You don't.

And that's why the first solution is beautiful. You can be quite sure that the standard would overload the trigonometric functions for a new type.

And please, don't say that the evaluation of a trigonometric function at initialization is a performance penalty.

2 Comments

Note that arg(log(x)) == π for all 0 < x < 1.
This is a terrible idea. use a per type overloaded template constexpr, that way you get a compile error to force you to define it if a new type appears. Its also generally a terrible because the trig types are not limited to floating point types. So enjoy the atan(1) mistake... The standard does not guarantee that trigonometric functions compute their actual trigonometric values to the accuracy of the type. They generally do not, and it gets worse with e.g. fastmath and is always especially bad for the special values.
18

In the C++20 standard library, π is defined as std::numbers::pi_v for float, double and long double, e.g.

#include <numbers> auto n = std::numbers::pi_v<float>; 

and may be specialized for user-defined types.

Comments

14

I use following in one of my common header in the project that covers all bases:

#define _USE_MATH_DEFINES #include <cmath> #ifndef M_PI #define M_PI (3.14159265358979323846) #endif #ifndef M_PIl #define M_PIl (3.14159265358979323846264338327950288) #endif 

On a side note, all of below compilers define M_PI and M_PIl constants if you include <cmath>. There is no need to add `#define _USE_MATH_DEFINES which is only required for VC++.

x86 GCC 4.4+ ARM GCC 4.5+ x86 Clang 3.0+ 

2 Comments

Can the downvoter comment on what is wrong with this answer. This is well researched and tested and being in use in real system. I had definitely like to improve it if something is wrong.
FYI, Borland C++ compilers also define M_PI without needing _USE_MATH_DEFINES
8

I generally prefer defining my own: const double PI = 2*acos(0.0); because not all implementations provide it for you.

The question of whether this function gets called at runtime or is static'ed out at compile time is usually not an issue, because it only happens once anyway.

1 Comment

It's often less CPU instructions and/or less latency to load an immediate operand than read an operand from a memory location. Also, only expressions that are known at compile-time could be pre-computed (I mean double x = pi * 1.5; and the like). If you ever intend to use PI in crunchy math in tight loops, you better make sure the value is known to the compiler.
7

I just came across this article by Danny Kalev which has a great tip for C++14 and up.

template<typename T> constexpr T pi = T(3.1415926535897932385); 

I thought this was pretty cool (though I would use the highest precision PI in there I could), especially because templates can use it based on type.

template<typename T> T circular_area(T r) { return pi<T> * r * r; } double darea= circular_area(5.5);//uses pi<double> float farea= circular_area(5.5f);//uses pi<float> 

1 Comment

3.1415926535897932385 is a double constant. Accuracy is lost when converting the numeral to double, and converting that double to long double leaves the value unchanged, with the accuracy lost.
5

Values like M_PI, M_PI_2, M_PI_4, etc are not standard C++ so a constexpr seems a better solution. Different const expressions can be formulated that calculate the same pi and it concerns me whether they (all) provide me the full accuracy. The C++ standard does not explicitly mention how to calculate pi. Therefore, I tend to fall back to defining pi manually. I would like to share the solution below which supports all kind of fractions of pi in full accuracy.

#include <ratio> #include <iostream> template<typename RATIO> constexpr double dpipart() { long double const pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899863; return static_cast<double>(pi * RATIO::num / RATIO::den); } int main() { std::cout << dpipart<std::ratio<-1, 6>>() << std::endl; } 

1 Comment

Very nice. It might be necessary to have an "l" or "L" at the end of that number. I get a narrowing warning from my compiler gcc on linux.
5

Some elegant solutions. I am doubtful that the precision of the trigonometric functions is equal to the precision of the types though. For those that prefer to write a constant value, this works for g++ :-

template<class T> class X { public: static constexpr T PI = (T) 3.14159265358979323846264338327950288419\ 71693993751058209749445923078164062862089986280348253421170679821480865132823066\ 47093844609550582231725359408128481117450284102701938521105559644622948954930381\ 964428810975665933446128475648233786783165271201909145648566923460; ... } 

256 decimal digit accuracy should be enough for any future long long long double type. If more are required visit https://www.piday.org/million/.

Comments

3
#include <cmath> const long double pi = acos(-1.L); 

1 Comment

I had the obvious question "why not constexpr?" and someone already answered this on stackoverflow.com/questions/32814678/…, which might be useful to somebody.
2

On windows (cygwin + g++), I've found it necessary to add the flag -D_XOPEN_SOURCE=500 for the preprocessor to process the definition of M_PI in math.h.

2 Comments

This is not an answer, but a comment to fritzone's answer.
@0xbadf00d: It is a completely standalone answer that provides the steps needed to get M_PI working on a particular platform. That isn't a comment on an answer for some other platform any more that an answer for some other platform is a comment on this one.
2

You can do this:

#include <cmath> #ifndef M_PI #define M_PI (3.14159265358979323846) #endif 

If M_PI is already defined in cmath, this won't do anything else than include cmath. If M_PI isn't defined (which is the case for example in Visual Studio), it will define it. In both cases, you can use M_PI to get the value of pi.

This value of pi comes from Qt Creator's qmath.h.

Comments

2

You can use that:

#define _USE_MATH_DEFINES // for C++ #include <cmath> #define _USE_MATH_DEFINES // for C #include <math.h> 

Math Constants are not defined in Standard C/C++. To use them, you must first define _USE_MATH_DEFINES and then include cmath or math.h.

1 Comment

That seems to be an implementation-specific extension not mentioned in the C or C++ standards. You should qualify this answer to mention which implementation(s) it applies to.
2

I've memorized pi to 11 digits since college (maybe high school), so this is always my preferred approach:

#ifndef PI #define PI 3.14159265359 #endif 

7 Comments

This is not a good solution since the standard headers will define π with a precision suitable for their C++ implementation. That is, they will use as many digits as needed to give π as accurately as the implementation is capable of. They may also use a hexadecimal format to avoid rounding issues in the conversion from decimal to the internal floating-point format. The standard headers should be preferred, and, if one is going to define π oneself, it would be with more digits.
What exactly does a "C++ implementation" have to do with the number of digits of pi? Are you referring to the bit width of the registers?
This is literally the only good answer to the question. It doesn't include any esoteric header files, doesn't run any further math of trig operations, and doesn't rely on assembly code. It just uses good old fashioned American high school knowledge of math. Kudos, good sir!
It literally doesn't answer the question, which asked for a solution without defining it manually. It is also a path to frustration to introduce inconsistent definitions of constants within the same program.
I have upvote because during writing in C++ for 10+ years I have never seen the definition of pi, seems C++20 fixes the issue. "solution without defining it manually." - is stupid, you can do whatever you want. And I'm not sure it's under the responsibility of C to define any constant from the math of physics.
|
2

I don't like #defines since they are simple textual substitutions with zero type safety. They can also cause problems using expressions if brackets are omitted e.g.

#define T_PI 2*PI 

should really be

#define T_PI (2*PI) 

My current solution to this problem is to use hard-coded values for constants, e.g. in my_constants.hxx

namespace Constants { constexpr double PI = 3.141... ; } 

However I do not hard-code the values (since I don't like that approach either), instead I use a separate Fortran program to write this file. I use Fortran because it fully supports quad precision (C++ on VisualStudio doesn't) and trig functions are the C++ equivalent of constexpr. E.g.

real(8), parameter :: pi = 4*atan(1.0d0) 

No doubt other languages can be used to do the same thing.

Comments

1

C++14 lets you do static constexpr auto pi = acos(-1);

7 Comments

std::acos is not a constexpr. So, your code won't compile.
@0xbadf00d I compiled it with g++
@WillyGoat: Then g++ is wrong, because acos is not constexpr in C++14, and is not proposed to become constexpr even in C++17
@wcochran: There are plenty of NEW math functions that are constexpr, see for example (github.com/kthohr/gcem). But they are not backward-compatible with the C functions of the same name, so they can't take over the old names.
This is a GCC extension and should not be used (stackoverflow.com/questions/32814678/…).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.