613

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?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Etan
  • 17,014
  • 17
  • 89
  • 148

25 Answers25

677

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 */
    
Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
  • 68
    `#define _USE_MATH_DEFINES` followed by `#include ` defines `M_PI` in visual c++. Thanks. – Etan Nov 13 '09 at 08:30
  • 3
    Works with cygwin headers as well. – Rob Mar 04 '11 at 05:35
  • 34
    You can always include `cmath` instead of `math.h`. – Richard J. Ross III Apr 15 '12 at 20:34
  • 13
    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 '14 at 10:44
  • 5
    As of 2018, The answer should definetely be updated to use instead of – Mariusz Jaskółka Dec 09 '18 at 11:11
  • @jaskmar I can't find an M_PI with included. However, the answer should perhaps be updated to say M_1_PI instead, because that's the defined value that I can find with included. There' also an M_2_PI, which is basically Tau. – Kapten-N Nov 19 '19 at 09:35
  • 1
    @Kapten-N M_1_PI is `1/pi`, not `pi` – sappjw Mar 15 '21 at 16:13
190

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

Konamiman
  • 49,681
  • 17
  • 108
  • 138
  • 89
    For c++11 users: `constexpr double pi() { return std::atan(1)*4; }` – matiu Sep 03 '12 at 16:17
  • 59
    -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? – Thomas Eding Oct 23 '12 at 23:49
  • 4
    @ThomasEding - my `math.h` file reads `#define M_PI 3.14159265358979323846` (if strict ANSI). – Ben Nov 27 '12 at 06:41
  • 32
    One can avoid the multiplication operation with `atan2(0, -1);`. – legends2k May 29 '13 at 21:18
  • 54
    @matiu `atan` is not `constexpr`. – R. Martinho Fernandes Sep 05 '13 at 15:28
  • 63
    Try `acos(-1)` instead, no need for `atan2`. – user541686 Jul 09 '14 at 11:52
  • 6
    @Pharap almost nothing: the only difference is that using `constexpr` enforces the value to be computed at compile time, while the old `const` do that at program initialization. – pqnet Aug 04 '14 at 09:20
  • 1
    @Pharap on my machine, with my compiler, atan(1)*4 generates pi at compile time. I'm not sure that this behavior is specified by the C++99 standard. Using constexpr is better. – jimifiki Apr 16 '15 at 08:49
  • 1
    @jimifiki I've yet to have someone tell me that their compiler doesn't do this when using `const` but does with `constexpr`. If you can find one that doesn't, then and only then will you have something to refute my claim. – Pharap Apr 16 '15 at 11:29
  • 5
    @ThomasEding it really should. Especially acos(-1) should give the closest value to pi, since -1 is a special case for acos. Fun fact: let M_PI = pi-delta, (i.e. delta is the rounding error), then library call sin(M_PI) should return delta, with precision of a double. I.e. sin(M_PI) + M_PI, the two added together exactly using suitable means, should give you pi with 100+ significant bits -- if 'sin' is done properly. I've tried this with glibc and it worked. – greggo Apr 26 '15 at 21:54
  • 2
    @greggo: What data type are you using that has 100+ significant bits? And does "done properly" mean to calculate the exact value without any numerical error? – HelloGoodbye Oct 16 '15 at 18:22
  • @HelloGoodbye plain doubles. 52 bits in M_PI and 52 in sin(M_PI). If you add those together with full precision you get 100 good bits of pi. 'properly' just means that it should give the best result representable for the exact input value, even though the 'fuzz' in x at x = M_PI, multiplied by the derivative of sin(x) at that point (i.e. -1) gives you a 'fuzz' at the function output which of the same magnitude as sin(x). So, from one point of view the result is all fuzz and need not be that accurate, but a library function should still respect the exact input and give the best result. – greggo Oct 17 '15 at 21:31
  • 2
    @HelloGoodbye specifically, the way I checked it was to obtain the values in python floats (which are 64-bit doubles), convert them to exact rational values with `val.as_integer_ratio()`, find the exact rational sum, and then print that out in decimal to as many places as needed using integer div and mod etc; then compare to published value of pi. Simpler way: you can just printf both original doubles using "%36.34f" and then add them on paper : 3.1415926535897931159979634685441852 + 0.0000000000000001224646799147353207 – greggo Oct 17 '15 at 21:43
  • @greggo You're right, I realized that the sin function only needs to calculate a value with as high precision as the data type allows. It sounds like an interesting trick in that case. – HelloGoodbye Oct 18 '15 at 09:08
  • @greggo But I'm wondering how you would construct a sin function that gives that kind precision? It wouldn't work with ordinary Maclaurin expansion, since you already after the two first terms will have a rounding error that is larger the desired precision if the argument is `M_PI`. But if you have found that the method you suggest works, the sin function you are using obviously does give that good precision, but how does it work? – HelloGoodbye Oct 18 '15 at 09:09
  • 1
    @HelloGoodbye it's done in the argument reduction. something like this: the sin function would start by reducing modulo pi, and it would use a extended accuracy value of pi for that. E.g. if you find that the input x is close to k * pi+x0, with x0 in +/- pi/2, you subtract k*MPI from it, and then you subtract k * pi0, where pi0 is the tiny difference between MPI and the true pi. So for x=MPI we have k=1, and the first subtraction gives exactly 0, and the second gives the more accurate residue. This also allows keeping accuracy with huge inputs like x= 1e20, where k is a really big number. – greggo Oct 19 '15 at 19:25
  • 2
    C++14, just do `static constexpr auto pi = acos(-1);` or just `M_PI` – Willy Goat Mar 21 '16 at 20:08
  • 3
    With Visual Studio Community, I get an error using constexpr. – Eivind Dahl Jun 02 '16 at 13:39
  • @Pharap here you go: https://godbolt.org/z/UsGxf5. gcc is actually the only compiler that generates the constant at compile time. Visual Studio and clang does it at runtime by calling atan. – Elviss Strazdins May 20 '20 at 03:16
  • @ElvissStrazdins Try icc. –  Sep 23 '20 at 22:01
  • 3
    @WillyGoat You're proving my private rule about the use of "just": the `acos` is just as non-constexpr as `atan` so your suggestion does not work. – Victor Eijkhout Feb 22 '21 at 17:14
169

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

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • 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. – Anachronist Feb 25 '21 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: https://stackoverflow.com/questions/15176290/what-is-long-double-on-x86-64 – Ciro Santilli OurBigBook.com Feb 25 '21 at 18:57
  • Why is the float value so far off? 3.xxxxxx74101257324219 ? It should be 3.14159265f – J. Tully Feb 27 '21 at 17:32
  • @J.Tully Google sugggests 7 figures is correct for 32-bit float: https://stackoverflow.com/questions/13542944/how-many-significant-digits-do-floats-and-doubles-have-in-java/50885022#50885022 I didn't stop to think myself though. – Ciro Santilli OurBigBook.com Feb 27 '21 at 19:14
  • 1
    @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 '21 at 06:01
128

Get it from the FPU unit on chip instead:

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

double PI = get_PI();
Henrik
  • 1,297
  • 1
  • 8
  • 2
  • 64
    :-) probably not that platform independent, but a nice additional exotic solution! – Etan Jun 04 '15 at 18:25
  • 9
    i love how you though out of the box here ;) – VivienLeger May 10 '18 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 '19 at 04:26
  • Having to load PI at runtime? Why... – user16217248 Jul 06 '23 at 18:45
  • 1
    @user16217248-OnStrike because you don't necessarily compile on the same machine on which you run. Perhaps the runtime machine has a tastier pi. – Adam Barnes Jul 07 '23 at 09:16
122

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.

BuschnicK
  • 5,304
  • 8
  • 37
  • 49
  • 243
    Boost: Boosting the already unnecessary complexity of C++ since 1999! – Dan Moulding Jul 28 '10 at 18:22
  • 50
    Catchy and partly true. On the other hand boost can be phenomenally useful at times... – BuschnicK Jul 29 '10 at 14:52
  • This won't work if you want to define a global variable PI. You will get an error shouting that `'pi' is not declared in this scope`. I am new to C++ so if there is a way to get around this I am not aware of it. – kalu Jul 15 '11 at 00:12
  • 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++. – Sebastian Mach Jul 09 '13 at 06:15
  • 7
    @phresnel seriously, boost is the only reason why c++ can be as easily written as php with a massive relative performance increase, not to mention its children: json-spirit & websocket++. –  Aug 10 '13 at 23:13
  • 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. – Sebastian Mach Aug 11 '13 at 10:22
  • 18
    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 03 '14 at 15:05
  • 5
    Why is there a boost answer to almost every C++ question? Boost should be another language otherwise it pollutes C++ – brettwhiteman Jul 14 '14 at 07:01
  • 1
    @Timmmm You might want to complain to the C++ standards committee about (b), because the STL uses it too now (see `std::numeric_limits`, among other things). – JAB Nov 19 '15 at 00:00
  • 1
    @JAB That is true, but at least it is only one nested namespace (and some of `numeric_limits` are constants rather than functions - I'm not sure why they used both approaches. Fortunately C++14 allows templated variables anyway so you could just do `double d = std::pi;` or whatever. – Timmmm Nov 19 '15 at 11:12
  • @Timmmm Boost seems to favor nested namespaces in general. I've found it useful to just alias the namespaces when you need to (e.g. `namespace bmc = boost::math::constants;` or whatever). I wasn't aware that C++14 allows templated variables, though, that's interesting (though technically previous versions allowed them too, they just had to be members of specializations of template classes, hence why you have to use `typename` to tell your compiler a dependent type is actually a type [though I still can't see why compilers can't determine that for themselves in non-ambiguous cases]). – JAB Nov 19 '15 at 13:32
  • *You could also use boost ...*. Right, but please don't redefine an already defined constant (in a less flexible way). – 0xbadf00d Mar 21 '16 at 12:51
  • 2
    @DanMoulding: The point of the boost::math::constants is that they are *arbitrary precision* constants. They can be used in (say) climate codes where quad precision is often required. – user14717 Sep 08 '19 at 17:24
53

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;
Francisco Presencia
  • 8,732
  • 6
  • 46
  • 90
Alex
  • 619
  • 5
  • 3
  • 32
    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 '14 at 01:47
  • 16
    If one is doing this in C++11, make the `const` a `constexpr`. – legends2k Jan 23 '14 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 '14 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. https://goo.gl/BvdJyr – Nemo Jan 23 '16 at 05:37
  • 3
    @Nemo, Counter example: https://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`. – Parker Coates Jan 04 '17 at 20:19
  • That's way more digits than you need. `3.1415927f` is as accurate as you can store with 32bit floats, and `3.141592653589793` is as accurate as you can store with 64bit doubles. – Jack G Feb 20 '21 at 03:04
  • Yes and no, Jack, have you heard that arithmetic is sometimes done in higher precision before rounding down? https://stackoverflow.com/a/25303561/1043529 (these are "float eval methods" but I believe there's even more to it.) I think the idea is that pi should be stored in significantly higher precision so that an expression like `M_PI - 3.14` ends up with the right number of digits of precision (starts with 1.59265*10^-3.) A real math whiz could tell you more. Oh, and they should be stored as #defines and not directly or you'll lose any excess digits. – John P Sep 04 '22 at 21:39
  • Here we go, same page: https://stackoverflow.com/a/25303263/1043529 : "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 04 '22 at 21:44
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.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 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. – Steve Jessop Nov 13 '09 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... – Matthieu M. Nov 13 '09 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. – Steve Jessop Nov 14 '09 at 03: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 `` 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 '15 at 02:18
41

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.

sellibitze
  • 27,611
  • 3
  • 75
  • 95
  • 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 09 '14 at 19:14
  • 2
    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(-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 02 '18 at 09: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 '20 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 04 '22 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 06 '23 at 17:47
  • @BenVoigt `ldexp(x, 2)` and `4*x` are actually identical. Were you trying to be helpful or funny? – John P Aug 02 '23 at 13:53
  • @JohnP: The mention of `ldexp` was to prove that there is no precision lost. The mantissa is entirely unchanged by an `ldexp` call; there is no rounding. – Ben Voigt Aug 02 '23 at 14:25
  • @BenVoigt You're right. Do you agree with what I said about recommending against storing directly in the data type? – John P Aug 02 '23 at 19:28
  • @JohnP: You're concerned that `atan(1.0)` is permitted to return a result with extended precision, and the multiplication can preserve that extended precision? (as mentioned above, multiply by 4 doesn't change mantissa bits so it neither creates nor destroys precision) But I see no alternative to storing to a constant of the appropriate data type, unless you're proposing a macro (but the disadvantages of macros are very well known). So I'm not sure what alternative you see to "storing directly in your data type" – Ben Voigt Aug 02 '23 at 19:36
40

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
जलजनक
  • 3,072
  • 2
  • 24
  • 30
Joakim
  • 401
  • 4
  • 3
27

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.

RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • Good news, everybody! It does now / it's about to. https://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 04 '22 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.

0xbadf00d
  • 17,405
  • 15
  • 67
  • 107
  • 1
    Note that `arg(log(x)) == π` for all `0 < x < 1`. – 0xbadf00d Feb 26 '16 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 '20 at 13:11
13

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+
Chris Nolet
  • 8,714
  • 7
  • 67
  • 92
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
  • 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. – Shital Shah Jul 19 '16 at 07:02
  • 1
    FYI, Borland C++ compilers also define `M_PI` without needing `_USE_MATH_DEFINES` – Remy Lebeau Jan 25 '18 at 19:20
11

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.

John McFarlane
  • 5,528
  • 4
  • 34
  • 38
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.

Sumudu Fernando
  • 1,763
  • 2
  • 11
  • 17
  • 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. – Eugene Ryabtsev Aug 19 '14 at 07: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>
dbc
  • 104,963
  • 20
  • 228
  • 340
Beta Jester
  • 79
  • 1
  • 2
  • 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. – Eric Postpischil Aug 30 '21 at 00: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/.

Jon Guiton
  • 1,360
  • 1
  • 9
  • 11
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;
}
  • 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. – Grant Rostig Feb 02 '19 at 00: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.

A.L
  • 10,259
  • 10
  • 67
  • 98
Papa Smurf
  • 375
  • 2
  • 7
  • 2
    This is not an answer, but a comment to fritzone's answer. – 0xbadf00d Feb 26 '16 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 09 '16 at 19:18
2

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

Willy Goat
  • 1,175
  • 2
  • 9
  • 24
  • 10
    `std::acos` is not a `constexpr`. So, your code won't compile. – 0xbadf00d May 05 '16 at 17:05
  • @0xbadf00d I compiled it with g++ – Willy Goat May 06 '16 at 03: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 09 '16 at 19:22
  • @BenVoigt are there any math functions that are `constexpr`? Apparently not: https://stackoverflow.com/questions/17347935/constexpr-math-functions – wcochran Feb 14 '20 at 22:01
  • 1
    @wcochran: There are plenty of NEW math functions that are `constexpr`, see for example (https://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 '20 at 22:05
  • @0xbadf00d: It compile but you cant use it in a constexpr context – Isaac Pascual Mar 03 '20 at 11:31
  • This is a GCC extension and should not be used (https://stackoverflow.com/questions/32814678/constexpr-compile-error-using-stdacos-with-clang-not-g). – Jeff Hammond Nov 10 '20 at 17:02
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.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
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);
gjerich
  • 369
  • 3
  • 6
  • I had the obvious question "why not constexpr?" and someone already answered this on https://stackoverflow.com/questions/32814678/constexpr-compile-error-using-stdacos-with-clang-not-g, which might be useful to somebody. – Jeff Hammond Nov 10 '20 at 17:00
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
stackoverflowuser2010
  • 38,621
  • 48
  • 169
  • 217
  • 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. – Eric Postpischil Aug 30 '21 at 00: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? – stackoverflowuser2010 Aug 30 '21 at 04: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! – stackoverflowuser2010 Aug 30 '21 at 17:12
  • @EricPostpischil: What's the answer, bro? – stackoverflowuser2010 Sep 03 '21 at 17:27
  • 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 01 '21 at 09: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. – Konstantin Burlachenko Dec 19 '21 at 21:48
  • What if the value of Pi changes? You'll have to go back and edit it manually. – parsley72 Apr 29 '22 at 03:58
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.

Simon
  • 21
  • 1
0

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.

Carl Knox
  • 9
  • 1
  • 2
    This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30342326) – Max Ostrowski Nov 15 '21 at 16:31