我想在一些c++程序中使用PI常数和三角函数。我得到三角函数包含<math。h>。然而,在这个头文件中似乎没有PI的定义。
如何获得PI而不手动定义它?
我想在一些c++程序中使用PI常数和三角函数。我得到三角函数包含<math。h>。然而,在这个头文件中似乎没有PI的定义。
如何获得PI而不手动定义它?
当前回答
因为官方标准库没有定义常数PI,你必须自己定义它。因此,对于你的问题“如何获得PI而不手动定义它?”的答案是“你没有——或者你依赖于一些特定于编译器的扩展。”如果你不关心可移植性,你可以查看编译器手册。
c++允许你编写
const double PI = std::atan(1.0)*4;
但是这个常数的初始化不能保证是静态的。然而,g++编译器将这些数学函数作为内在函数处理,并能够在编译时计算这个常量表达式。
其他回答
我建议你只输入你需要的精度。这不会为您的执行增加计算时间,并且无需使用任何头文件或#define即可移植。计算acos或atan总是比使用预先计算的值更昂贵。
const double PI =3.141592653589793238463;
const float PI_F=3.14159265358979f;
在c++ 20标准库中,π被定义为std::numbers::pi_v,用于浮点数、双精度数和长双精度数。
#include <numbers>
auto n = std::numbers::pi_v<float>;
并且可以专门化为用户定义的类型。
你可以这样做:
#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。
我不喜欢#定义,因为它们是零类型安全的简单文本替换。如果省略括号,它们也会在使用表达式时引起问题。
#define T_PI 2*PI
真的应该
#define T_PI (2*PI)
我目前对这个问题的解决方案是使用常量的硬编码值,例如my_constants.hxx
namespace Constants {
constexpr double PI = 3.141... ;
}
但是我没有硬编码这些值(因为我也不喜欢这种方法),而是使用一个单独的Fortran程序来编写这个文件。我使用Fortran是因为它完全支持四精度(VisualStudio上的c++不支持),三角函数是c++的constexpr等价函数。 如。
real(8), parameter :: pi = 4*atan(1.0d0)
毫无疑问,其他语言也可以用来做同样的事情。
我通常更喜欢自己定义:const double PI = 2*acos(0.0);因为不是所有的实现都为您提供它。
这个函数是在运行时被调用还是在编译时被静态输出的问题通常不是问题,因为它只会发生一次。