我想在一些c++程序中使用PI常数和三角函数。我得到三角函数包含<math。h>。然而,在这个头文件中似乎没有PI的定义。
如何获得PI而不手动定义它?
我想在一些c++程序中使用PI常数和三角函数。我得到三角函数包含<math。h>。然而,在这个头文件中似乎没有PI的定义。
如何获得PI而不手动定义它?
当前回答
我会这么做
template<typename T>
T const pi = std::acos(-T(1));
or
template<typename T>
T const pi = std::arg(-std::log(T(2)));
我不会把π输入到你需要的精度。这到底是什么意思?你需要的精度是T的精度,但是我们对T一无所知。
你可能会说:What are You talking about?T是float, double或long double。因此,只需输入long double的精度,即。
template<typename T>
T const pi = static_cast<T>(/* long double precision π */);
但是你真的知道在未来的标准中不会有比long double精度更高的新的浮点类型吗?你不。
这就是为什么第一个解很漂亮。可以肯定的是,这个标准将会使三角函数过载而产生一种新的类型。
请不要说三角函数在初始化时的计算是性能损失。
其他回答
因为官方标准库没有定义常数PI,你必须自己定义它。因此,对于你的问题“如何获得PI而不手动定义它?”的答案是“你没有——或者你依赖于一些特定于编译器的扩展。”如果你不关心可移植性,你可以查看编译器手册。
c++允许你编写
const double PI = std::atan(1.0)*4;
但是这个常数的初始化不能保证是静态的。然而,g++编译器将这些数学函数作为内在函数处理,并能够在编译时计算这个常量表达式。
而是从芯片上的FPU单元获取:
double get_PI()
{
double pi;
__asm
{
fldpi
fstp pi
}
return pi;
}
double PI = get_PI();
我会这么做
template<typename T>
T const pi = std::acos(-T(1));
or
template<typename T>
T const pi = std::arg(-std::log(T(2)));
我不会把π输入到你需要的精度。这到底是什么意思?你需要的精度是T的精度,但是我们对T一无所知。
你可能会说:What are You talking about?T是float, double或long double。因此,只需输入long double的精度,即。
template<typename T>
T const pi = static_cast<T>(/* long double precision π */);
但是你真的知道在未来的标准中不会有比long double精度更高的新的浮点类型吗?你不。
这就是为什么第一个解很漂亮。可以肯定的是,这个标准将会使三角函数过载而产生一种新的类型。
请不要说三角函数在初始化时的计算是性能损失。
我从大学(也许是高中)就开始背圆周率到11位,所以这一直是我的首选方法:
#ifndef PI
#define PI 3.14159265359
#endif
一些优雅的解决方案。不过,我怀疑三角函数的精度是否等于类型的精度。对于那些喜欢编写常量值的人来说,这适用于g++:-
template<class T>
class X {
public:
static constexpr T PI = (T) 3.14159265358979323846264338327950288419\
71693993751058209749445923078164062862089986280348253421170679821480865132823066\
47093844609550582231725359408128481117450284102701938521105559644622948954930381\
964428810975665933446128475648233786783165271201909145648566923460;
...
}
256十进制数字的精度应该足以用于任何未来的长长长双精度类型。如果需要更多信息,请访问https://www.piday.org/million/。