C + + 11、14、17或20是否为 π 引入了一个标准常数?

在 C 和 C + + 中,π 这个数字有一个相当愚蠢的问题。据我所知,math.h中定义的 M_PI并不是任何标准所要求的。

新的 C + + 标准在标准库中引入了许多复杂的数学问题——双曲函数、 std::hermitestd::cyl_bessel_i、不同的随机数生成器等等。

有没有任何“新”标准为 π 带来了一个常数?如果不是,为什么?没有它,这些复杂的数学怎么算?

我知道 C + + 中关于 π 的类似问题(它们已经有好几年的历史了,标准也已经过时了) ; 我想知道问题的当前状态。

到 C + + 20为止,没有一个标准引入了表示 圆周率(π)的常数。您可以在代码中大致估算出这个数字:

constexpr double pi = 3.14159265358979323846;

我对 为什么,为什么 C + + 也很感兴趣,它仍然没有 π 常数,但是有很多更复杂的数学。

我知道我可以把 π 定义为 4*atan(1)acos(-1)double pi = 3.14;。当然。但为什么我还是要这么做?没有圆周率,标准数学函数是如何工作的?

39823 次浏览

其他语言,例如 C # ,在它们的库中声明的常量。

更新: 从 C + + 20开始,确实在 <numbers>报头中声明了一个 pi常量。

的确依赖于这种功能的基础。

到 C + + 17圆周率为止并包括在内,圆周率并不是引入到语言中的一个常量,而且它是一个令人头疼的问题。

有一种使用元编程获取 圆周率constexpr值的方法: 参见 http://timmurphy.org/2013/06/27/template-metaprogramming-in-c/


我很幸运,因为我使用的是 加速,而他们定义的 圆周率的小数位足够大甚至是128位的 long double

来自 C + + 20的一些好消息。这里 圆周率的定义。C + + 20在 <numbers>中添加了一些数学常数。例如,std::numbers::pidouble类型。

如果您不使用 Boost,那么自己硬编码它。用一个三角函数来定义它是很诱人的,但是如果你这样做了,你就不能把它变成一个 constexpr。我所知道的任何标准(ABc2)也无法保证三角函数的准确性。std::sqrt) ,所以你真的是在危险的地方,真的依赖于这样的功能。

参考资料: https://en.cppreference.com/w/cpp/numeric/constants

如果您不使用 Boost,那么自己硬编码它。用一个三角函数来定义它是很诱人的,但是如果你这样做了,你就不能把它变成一个 constexpr。我所知道的任何标准(ABc2)也无法保证三角函数的准确性。std::sqrt) ,所以你真的是在危险的地方,真的依赖于这样的功能。

有一种使用元编程获取 圆周率constexpr值的方法: 参见 http://timmurphy.org/2013/06/27/template-metaprogramming-in-c/


正如其他人所说,没有 std::pi,但是如果你想要精确的 PI值,你可以使用:

constexpr double pi = std::acos(-1);

来自 C + + 20的一些好消息。这里 圆周率的定义。C + + 20在 <numbers>中添加了一些数学常数。例如,std::numbers::pidouble类型。

参考资料: https://en.cppreference.com/w/cpp/numeric/constants

这假设您的 C + + 实现从 acos(-1.0)这很常见,但不能保证生成一个正确舍入的 PI 值。

它不是 constexpr,但在实践中优化编译器(如 gcc 和 clang)会在编译时对它进行评估。不过,声明它为 const对优化器做好工作非常重要。

这显然不是一个好主意,因为没有明显的类型来定义在各个领域都普遍适用的 π。

每次使用圆周率的代价。

对于任何程序员来说,找到 pi 的值并定义适合使用的常数也是微不足道的,因此将它包含在数学标题中没有任何好处。

当然,π 是一个无理数,所以它不能正确地用 任何 c + + 类型表示。因此,您可能会争辩说,自然的方法是在可用的最大浮点类型中定义它。但是,最大的标准浮点类型 long double的大小不是由 C + + 标准定义的,因此常数的值在不同的系统之间会有所不同。更糟糕的是,对于任何工作类型不是这种最大类型的程序,π 的定义都是不合适的,因为它会对每次使用 π 造成性能损失。

对于任何程序员来说,找到 pi 的值并定义适合使用的常数也是微不足道的,因此将它包含在数学标题中没有任何好处。

与此同时,C + + 20确实有 这些常数(在 C + + 20的最后一轮中合并的特性)。具体来说,如果需要不同的浮点类型(例如 std::numbers::pi_v<float>) ,可以同时使用 std::numbers::pi(类型为 double)和变量模板。