Currently in one my scientific computation codes I have the following:
//Include M_PI constant
#define _USE_MATH_DEFINES
//Needed for square root function.
#include <math.h>
This works... on Linux at least... I have not tested it for C compilers on all platforms. However, when surveying some older Fortran codes, I recently came across this seemingly clever way of defining pi in another code (not my own):
<angle in deg.>*8.0d0 * datan(1.0d0) / 360.0d0
Of course this is perfectly feasible in C, right? So I could define my conversion function something like:
inline double DegToRad(const double A)
{
return A * atan(1.0) / 45.0;
}
Which approach is more portable? Are there any numeric (e.g. rounding) considerations that would merit using one approach over another?
I do like that the M_PI constants make the code more readable. Of course, I could happily just assign my own PI constant using the above approach.
What is considered best practice in C/C++ codes that are going to be targeted at multiple platforms (Windows, Linux, etc.)?
Don't minimize the readability issue; personally, I'd do something like this:
#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)
and then declare
inline double DegToRad(const double deg) {
return deg * DEG_TO_RAD;
}
inline double RadToDeg(const double rad) {
return rad * RAD_TO_DEG;
}
This is probably not going to be any more or less portable (both atan
and M_PI
are standard in both C and C++). However it will be more readable than using atan
and depending on your compiler's optimization settings, may save you a costly trig function call.
UPDATE: It looks like M_PI isn't as standard as I thought. Inclusion of the #ifndef
above should take care of the instances where it's not available.