如何在 C++ 中使用 PI 常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1727881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use the PI constant in C++
提问by Etan
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.
我想在一些 C++ 程序中使用 PI 常数和三角函数。我得到三角函数include <math.h>
。但是,这个头文件中似乎没有对 PI 的定义。
How can I get PI without defining it manually?
如何在不手动定义的情况下获得 PI?
回答by Ferenc Deak
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:
可以通过以下方式访问 pi 的值:
M_PI
In my math.h
(2014) it is defined as:
在我的math.h
(2014)中,它被定义为:
# define M_PI 3.14159265358979323846 /* pi */
but check your math.h
for more. An extract from the "old" math.h
(in 2009):
但检查你math.h
的更多。摘自“旧” math.h
(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:
然而:
on newer platforms (at least on my 64 bit Ubuntu 14.04) I do not need to define the
_USE_MATH_DEFINES
On (recent) Linux platforms there are
long double
values too provided as a GNU Extension:# define M_PIl 3.141592653589793238462643383279502884L /* pi */
在较新的平台上(至少在我的 64 位 Ubuntu 14.04 上)我不需要定义
_USE_MATH_DEFINES
在(最近的)Linux 平台上,
long double
也提供了作为 GNU 扩展的值:# define M_PIl 3.141592653589793238462643383279502884L /* pi */
回答by Konamiman
Pi can be calculated as atan(1)*4
. You could calculate the value this way and cache it.
Pi 可以计算为atan(1)*4
。您可以通过这种方式计算值并将其缓存。
回答by BuschnicK
You could also use boost, which defines important math constants with maximum accuracy for the requested type (i.e. float vs double).
您还可以使用 boost,它为所请求的类型(即 float 与 double)定义具有最大精度的重要数学常数。
const double pi = boost::math::constants::pi<double>();
Check out the boost documentationfor more examples.
查看boost 文档以获取更多示例。
回答by Henrik
Get it from the FPU unit on chip instead:
从芯片上的 FPU 单元获取它:
double get_PI()
{
double pi;
__asm
{
fldpi
fstp pi
}
return pi;
}
double PI = get_PI();
回答by Alex
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.
我建议只输入 pi 到您需要的精度。这不会为您的执行增加计算时间,并且无需使用任何标题或 #defines 即可移植。计算 acos 或 atan 总是比使用预先计算的值更昂贵。
const double PI =3.141592653589793238463;
const float PI_F=3.14159265358979f;
回答by Matthieu M.
Rather than writing
而不是写作
#define _USE_MATH_DEFINES
I would recommend using -D_USE_MATH_DEFINES
or /D_USE_MATH_DEFINES
depending on your compiler.
我建议使用-D_USE_MATH_DEFINES
或/D_USE_MATH_DEFINES
取决于您的编译器。
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.
通过这种方式,您可以放心,即使有人在您这样做之前(并且没有 #define)包含了标头,您仍然会拥有常量,而不是您需要花费很长时间才能找到的晦涩编译器错误。
回答by sellibitze
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.
由于官方标准库没有定义常量 PI,因此您必须自己定义它。所以你的问题的答案“如何在不手动定义的情况下获得 PI?” 是“你没有——或者你依赖一些特定于编译器的扩展。”。如果您不关心可移植性,您可以查看您的编译器手册。
C++ allows you to write
C++ 允许你写
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.
但不能保证这个常量的初始化是静态的。然而,G++ 编译器将这些数学函数作为内在函数处理,并且能够在编译时计算这个常量表达式。
回答by Joakim
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
回答by RichieHindle
Standard C++ doesn't have a constant for PI.
标准 C++ 没有用于 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.
许多 C++ 编译器将M_PI
in cmath
(或 in math.h
for C)定义为非标准扩展。您可能必须#define _USE_MATH_DEFINES
先看到它。
回答by 0xbadf00d
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 nottyping in π to the precision you need. What is that even supposed to mean? The precision you needis the precision of T
, but we know nothing about T
.
我不会输入 π 到您需要的精度。这到底是什么意思?在你需要的精度是精度T
,但我们并不知道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.
你可能会说:你在说什么?T
将float
,double
或long double
。所以,只需输入精度long double
,即
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.
但是你真的知道未来标准中不会有比 精度更高的新浮点类型long double
吗?你没有。
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.
并且请不要说在初始化时对三角函数的评估是一种性能损失。