views:

4590

answers:

8

I want to use the PI constant and trigonometric functions in some C++ program. I get the trigonometric functions with include <math.h>. However, there doesn't seem to be a definition for PI in this header file.

How can I get PI without defining it manually?

+4  A: 

Pi can be calculated as atan(1)*4. You could calculate the value this way and cache it.

Konamiman
Downvoter, please explain what I said that is incorrect.
Konamiman
For "par condicio", you've been updvoted, since you are absolutely correct :-)
Enrico Detoma
+1  A: 

M_PI in the cmath seem to be standard.

RageZ
Depending on your definition of "standard"
sellibitze
@sellibitze: good point, I thought it was standard but doesn't seems so
RageZ
+4  A: 

Standard C++ doesn't have a constant for PI.

Many C++ compilers define M_PI in cmath (or in math.h for C) as a non-standard extension. You may have to #define _USE_MATH_DEFINES before you can see it.

RichieHindle
+13  A: 

On some platforms you might need to

#define _USE_MATH_DEFINES

and then

M_PI

is your friend. Check for more. Taken from my math. h:

/* Define _USE_MATH_DEFINES before including math.h to expose these macro
 * definitions for common math constants.  These are placed under an #ifdef
 * since these commonly-defined names are not part of the C/C++ standards.
 */
fritzone
`#define _USE_MATH_DEFINES` followed by `#include <math.h>` defines `M_PI` in visual c++. Thanks.
Etan
+4  A: 

Since the official standard library doesn't define a constant PI you would have to define it yourself. So the answer to your question "How can I get PI without defining it manually?" is "You don't -- or you rely on some compiler-specific extensions.". If you're not concerned about portability you could check your compiler's manual for this.

C++ allows you to write

const double PI = std::atan(1.0)*4;

but the initialization of this constant is not guaranteed to be static. The G++ compiler however handles those math functions as intrinsics and is able to compute this constant expression at compile-time.

sellibitze
+1  A: 

Rather than writing

#define _USE_MATH_DEFINES

I would recommend using -D_USE_MATH_DEFINES or /D_USE_MATH_DEFINES depending on your compiler.

This way you are assured that even in the event of someone including the header before you do (and without the #define) you will still have the constants instead of an obscure compiler error that you will take ages to track down.

Matthieu M.
Good tip. If "you" are a compilation unit then of course you can ensure the macro is defined before anything is included. But if "you" are a header file, it's out of your control.
Steve Jessop
In fact even if "you" are a compilation unit... depending on the ordering of the headers is a the shortest path toward maintenance nightmare...
Matthieu M.
You don't have to depend on the ordering of the headers, though. It doesn't matter whether headers include each other, provided that you do the #define before you #include anything at all (at least, assuming that nothing #undefs it). Same applies to NDEBUG.
Steve Jessop
+6  A: 

You could also use boost, which defines important math constants with maximum accuracy for the requested type (i.e. float vs double).

const double pi = boost::math::constants::pi<double>();

Check out the boost documentation for more examples.

BuschnicK
Boost: Boosting the already unnecessary complexity of C++ since 1999!
Dan Moulding
Catchy and partly true. On the other hand boost can be phenomenally useful at times...
BuschnicK
+1  A: 

I generally prefer defining my own: const double PI = 2*acos(0.0); because not all implementations provide it for you.

The question of whether this function gets called at runtime or is static'ed out at compile time is usually not an issue, because it only happens once anyway.

Sumudu Fernando