Does C++11, 14, 17 or 20 introduce a standard constant for pi?
Solution 1:
Up to and including C++17 pi is not a constant introduced into the language, and it's a pain in the neck.
I'm fortunate in that I use boost and they define pi with a sufficiently large number of decimal places for even a 128 bit long double
.
If you don't use Boost then hardcode it yourself. Defining it with a trigonometric function is tempting but if you do that you can't then make it a constexpr
. The accuracy of the trigonometric functions is also not guaranteed by any standard I know of (cf. std::sqrt
), so really you are on dangerous ground indeed relying on such a function.
There is a way of getting a constexpr
value for pi using metaprogramming: see http://timmurphy.org/2013/06/27/template-metaprogramming-in-c/
From C++20 some good news. There is a defininition for pi. C++20 adds some mathematical constants in <numbers>
. For example std::numbers::pi
is a double
type.
Reference: https://en.cppreference.com/w/cpp/numeric/constants
Solution 2:
Up to C++20, no, none of the standards introduced the constant that would represent the number pi (π). You can approximate the number in your code:
constexpr double pi = 3.14159265358979323846;
Other languages such as C# have the constant declared in their libraries.
Update:
Starting with the C++20, there indeed is a pi
constant declared inside the <numbers>
header. It is accessed via: std::numbers::pi
.
Solution 3:
As others said there is no std::pi
but if you want precise PI
value you can use:
constexpr double pi = std::acos(-1);
This assumes that your C++ implementation produces a correctly-rounded value of PI from acos(-1.0)
, which is common but not guaranteed.
It's not constexpr
, but in practice optimizing compilers like gcc and clang evaluate it at compile time. Declaring it const
is important for the optimizer to do a good job, though.
Solution 4:
M_PI
is defined by "a standard", if not a language standard: POSIX with the X/Open System Interfaces extension (which is very commonly supported and required for official UNIX branding).
C++20, meanwhile, does have such constants (merged in the last round of C++20 features). Specifically, there is both std::numbers::pi
(of type double
) and a variable template that you can use if you want a different floating point type, e.g. std::numbers::pi_v<float>
.