在C/C++中定义PI的更好/更便携的方法?

Jas*_*ick 4 c math portability constants angle

目前在我的科学计算代码中,我有以下内容:

//Include M_PI constant
#define _USE_MATH_DEFINES
//Needed for square root function.
#include <math.h>
Run Code Online (Sandbox Code Playgroud)

这工作......至少在Linux上...我没有在所有平台上为C编译器测试它.但是,在调查一些较旧的Fortran代码时,我最近遇到了这种看似聪明的方法,即在另一个代码中定义pi(不是我自己的代码):

<angle in deg.>*8.0d0 * datan(1.0d0) / 360.0d0
Run Code Online (Sandbox Code Playgroud)

当然这在C中完全可行,对吧?所以我可以定义我的转换函数:

inline double DegToRad(const double A)
{
   return A * atan(1.0) / 45.0;
}
Run Code Online (Sandbox Code Playgroud)

哪种方法更便携?是否有任何数字(例如舍入)考虑因素值得使用一种方法而不是另一种方法?

我确实认为M_PI常量使代码更具可读性.当然,我可以愉快地使用上述方法分配我自己的PI常量.

什么被认为是针对多个平台(Windows,Linux等)的C/C++代码的最佳实践?

and*_*and 6

不要将可读性问题降至最低; 就个人而言,我会做这样的事情:

#ifndef M_PI
// Source: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
#define M_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406 
#endif

#define DEG_TO_RAD (M_PI/180.0)
#define RAD_TO_DEG (180.0/M_PI)
Run Code Online (Sandbox Code Playgroud)

然后宣布

inline double DegToRad(const double deg) {
   return deg * DEG_TO_RAD;
}

inline double RadToDeg(const double rad) {
   return rad * RAD_TO_DEG;
}
Run Code Online (Sandbox Code Playgroud)

这可能不会是任何或多或少便携式的(两者atanM_PI处于C和C++标准).但是它比使用更具可读性,atan并且根据编译器的优化设置,可以节省昂贵的trig函数调用.

更新:看起来M_PI不像我想象的那么标准.包含#ifndef上述内容应该注意不可用的情况.

  • 如果您遇到一个不符合标准的旧编译器,您可以简单地定义自己的`M_PI`,用`#ifndef M_PI`括起来... ...#endif` (2认同)