我想在一些c++程序中使用PI常数和三角函数。我得到三角函数包含<math。h>。然而,在这个头文件中似乎没有PI的定义。

如何获得PI而不手动定义它?


当前回答

标准c++没有圆周率的常数。

许多c++编译器在cmath中定义M_PI(或在math.h中定义C)作为一个非标准扩展。在看到它之前,您可能必须#define _use_math_definitions。

其他回答

而不是写作

#define _USE_MATH_DEFINES

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

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

Pi可计算为atan(1)*4。您可以这样计算值并缓存它。

M_PI, M_PI_2, M_PI_4等值不是标准的c++,因此constexpr似乎是更好的解决方案。不同的const表达式可以计算相同的pi,它关心我是否他们(所有)提供了完整的精度。c++标准没有明确提到如何计算圆周率。因此,我倾向于手动定义圆周率。我想分享下面的解决方案,它支持圆周率的所有分数的完全准确。

#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;
}

我刚刚看到了Danny Kalev写的一篇文章,它为c++ 14及以上版本提供了一个很好的建议。

template<typename T>
constexpr T pi = T(3.1415926535897932385);

我认为这非常酷(尽管我会在其中使用最高精度的PI),特别是因为模板可以基于类型使用它。

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>

在c++ 20标准库中,π被定义为std::numbers::pi_v,用于浮点数、双精度数和长双精度数。

#include <numbers>
auto n = std::numbers::pi_v<float>;

并且可以专门化为用户定义的类型。