633

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

25 Answers 25

694

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 */
    
9
  • 70
    #define _USE_MATH_DEFINES followed by #include <math.h> defines M_PI in visual c++. Thanks.
    – Etan
    Nov 13, 2009 at 8:30
  • 3
    Works with cygwin headers as well.
    – Rob
    Mar 4, 2011 at 5:35
  • 37
    You can always include cmath instead of math.h. Apr 15, 2012 at 20:34
  • 14
    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;.
    – legends2k
    Jan 23, 2014 at 10:44
  • 6
    As of 2018, The answer should definetely be updated to use <cmath> instead of <math.h> Dec 9, 2018 at 11:11
195

C++20 std::numbers::pi

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

main.cpp

#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;
}

where 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

Compile and run:

g++-10 -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

Tested on Ubuntu 20.04 amd64, GCC 10.2.0

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

5
  • 1
    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. Feb 25, 2021 at 15:43
  • @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/… Feb 25, 2021 at 18:57
  • Why is the float value so far off? 3.xxxxxx74101257324219 ? It should be 3.14159265f
    – J. Tully
    Feb 27, 2021 at 17:32
  • @J.Tully Google sugggests 7 figures is correct for 32-bit float: stackoverflow.com/questions/13542944/… I didn't stop to think myself though. Feb 27, 2021 at 19:14
  • 2
    @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.
    – Arnaud
    May 12, 2021 at 6:01
194

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

21
  • 91
    For c++11 users: constexpr double pi() { return std::atan(1)*4; }
    – matiu
    Sep 3, 2012 at 16:17
  • 60
    -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? Oct 23, 2012 at 23:49
  • 33
    One can avoid the multiplication operation with atan2(0, -1);.
    – legends2k
    May 29, 2013 at 21:18
  • 56
    @matiu atan is not constexpr. Sep 5, 2013 at 15:28
  • 64
    Try acos(-1) instead, no need for atan2.
    – user541686
    Jul 9, 2014 at 11:52
132

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
  • 66
    :-) probably not that platform independent, but a nice additional exotic solution!
    – Etan
    Jun 4, 2015 at 18:25
  • 9
    i love how you though out of the box here ;) May 10, 2018 at 20:49
  • 3
    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!
    – Matt
    Feb 25, 2019 at 4:26
  • Having to load PI at runtime? Why...
    – CPlus
    Jul 6, 2023 at 18:45
  • 2
    @user16217248-OnStrike because you don't necessarily compile on the same machine on which you run. Perhaps the runtime machine has a tastier pi. Jul 7, 2023 at 9:16
123

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
  • 243
    Boost: Boosting the already unnecessary complexity of C++ since 1999! Jul 28, 2010 at 18:22
  • 50
    Catchy and partly true. On the other hand boost can be phenomenally useful at times...
    – BuschnicK
    Jul 29, 2010 at 14:52
  • 65
    @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++. Jul 9, 2013 at 6:15
  • 11
    @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. Aug 11, 2013 at 10:22
  • 19
    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.
    – Timmmm
    Apr 3, 2014 at 15:05
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;
8
  • 34
    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.
    – nacho4d
    Jan 21, 2014 at 1:47
  • 18
    If one is doing this in C++11, make the const a constexpr.
    – legends2k
    Jan 23, 2014 at 10:51
  • 4
    @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.
    – m24p
    Feb 20, 2014 at 16:17
  • 3
    "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. goo.gl/BvdJyr
    – Nemo
    Jan 23, 2016 at 5:37
  • 3
    @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. Jan 4, 2017 at 20:19
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
  • 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. Nov 13, 2009 at 19:18
  • 3
    In fact even if "you" are a compilation unit... depending on the ordering of the headers is a the shortest path toward maintenance nightmare... Nov 13, 2009 at 19:37
  • 1
    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. Nov 14, 2009 at 3:13
  • 2
    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.
    – meneldal
    May 18, 2015 at 2:18
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
  • 9
    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.
    – Micah
    Sep 9, 2014 at 19:14
  • 3
    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).
    – tobi_s
    Oct 2, 2018 at 9:05
  • 1
    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.
    – midjji
    May 13, 2020 at 13:05
  • 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."
    – John P
    Sep 4, 2022 at 21:46
  • @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)
    – Ben Voigt
    Jul 6, 2023 at 17:47
41

From the Posix man page 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 pi

   M_PI_2 Value of pi/2

   M_PI_4 Value of pi/4

   M_1_PI Value of 1/pi

   M_2_PI Value of 2/pi

   M_2_SQRTPI
          Value of 2/ sqrt pi
1
28

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
  • 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.
    – John P
    Sep 4, 2022 at 21:48
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
  • 1
    Note that arg(log(x)) == π for all 0 < x < 1.
    – 0xbadf00d
    Feb 26, 2016 at 12:45
  • 2
    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.
    – midjji
    May 13, 2020 at 13:11
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
  • 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. Jul 19, 2016 at 7:02
  • 1
    FYI, Borland C++ compilers also define M_PI without needing _USE_MATH_DEFINES Jan 25, 2018 at 19:20
13

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.

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
  • 3
    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. Aug 19, 2014 at 7:55
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
  • 1
    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. Aug 30, 2021 at 0:16
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/.

4

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
  • 2
    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. Feb 2, 2019 at 0:29
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
  • 2
    This is not an answer, but a comment to fritzone's answer.
    – 0xbadf00d
    Feb 26, 2016 at 12:47
  • 2
    @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.
    – Ben Voigt
    Jun 9, 2016 at 19:18
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.

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.

2
#include <cmath>
const long double pi = acos(-1.L);
1
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
  • 1
    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. Aug 30, 2021 at 0:11
  • 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? Aug 30, 2021 at 4:24
  • 1
    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! Aug 30, 2021 at 17:12
  • 1
    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.
    – mabraham
    Oct 1, 2021 at 9:33
  • 1
    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. Dec 19, 2021 at 21:48
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.

1

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

7
  • 10
    std::acos is not a constexpr. So, your code won't compile.
    – 0xbadf00d
    May 5, 2016 at 17:05
  • @0xbadf00d I compiled it with g++
    – Willy Goat
    May 6, 2016 at 3:00
  • 13
    @WillyGoat: Then g++ is wrong, because acos is not constexpr in C++14, and is not proposed to become constexpr even in C++17
    – Ben Voigt
    Jun 9, 2016 at 19:22
  • 1
    @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.
    – Ben Voigt
    Feb 14, 2020 at 22:05
  • 1
    This is a GCC extension and should not be used (stackoverflow.com/questions/32814678/…). Nov 10, 2020 at 17:02
-2

15 decimal places got man to the lunar surface and back. Anything beyond this is astronomical in scale. Would you be able to measure this, practically, on a smaller scale? Others have spent months calculating to trillions of digits. This isn't useful beyond getting into the record books.

Know that you can calculate pi to an arbitrary length, but keep is practical.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.