我想在一些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精度更高的新的浮点类型吗?你不。

这就是为什么第一个解很漂亮。可以肯定的是,这个标准将会使三角函数过载而产生一种新的类型。

请不要说三角函数在初始化时的计算是性能损失。

其他回答

我通常更喜欢自己定义:const double PI = 2*acos(0.0);因为不是所有的实现都为您提供它。

这个函数是在运行时被调用还是在编译时被静态输出的问题通常不是问题,因为它只会发生一次。

而不是写作

#define _USE_MATH_DEFINES

我建议使用- use_math_definitions或/ d_use_math_definitions,这取决于你的编译器。

通过这种方式,即使有人在您之前包含了头文件(并且没有使用#define),您仍然可以得到常量,而不是一个晦涩的编译器错误,您需要花费很长时间来查找。

来自math.h的Posix手册页:

   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

一些优雅的解决方案。不过,我怀疑三角函数的精度是否等于类型的精度。对于那些喜欢编写常量值的人来说,这适用于g++:-

template<class T>
class X {
public:
            static constexpr T PI = (T) 3.14159265358979323846264338327950288419\
71693993751058209749445923078164062862089986280348253421170679821480865132823066\
47093844609550582231725359408128481117450284102701938521105559644622948954930381\
964428810975665933446128475648233786783165271201909145648566923460;
...
}

256十进制数字的精度应该足以用于任何未来的长长长双精度类型。如果需要更多信息,请访问https://www.piday.org/million/。

你可以这样做:

#include <cmath>
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif

如果M_PI已经在cmath中定义,那么除了包含cmath之外,它不会做任何其他事情。如果M_PI没有定义(在Visual Studio中就是这种情况),它会定义它。在这两种情况下,都可以使用M_PI来获取pi的值。

这个圆周率值来自Qt Creator的qmath.h。