1

I am working on a new project and I am trying to write the cleanest, easiest to read and hopefully, most efficient, code I can.

I need to use PI but apparently it isn't defined in math.h. So I read about doing this:

const double PI = atan(1.0)*4

But I get this error:

A function call cannot appear in a constant-expression

Any ideas on why? How can I get PI as a constant?

Also, please, I am trying to learn as much as I can with this project, so it would be great if you could also explain why your answer would work. Thanks!

Chris
  • 6,914
  • 5
  • 54
  • 80
coconut
  • 1,074
  • 4
  • 12
  • 30

4 Answers4

7

How about:

const double PI = 3.1415926535897932384626433832795028841971693993751058209;

This seems to me to be cleaner, easier to read, and more efficient than atan(1.0)*4.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • +1 and worth to say that double has about 17 significant decimal places, the floating point literal therefore can be much shorter. – Christian Ammer Jan 27 '12 at 22:08
  • 1
    @Christian : That's true on most common platforms, but ultimately it's implementation-defined; there are platforms with 128-bit doubles (yielding ~34 decimal numbers) that could take advantage of this declaration, and meanwhile it doesn't negatively affect the platforms that don't. – ildjarn Jan 27 '12 at 22:11
5

You have mis-tagged the question. In C++ the following is well-defined and will compile:

#include <math.h>

const double PI = atan(1.0)*4;

But in C, initializers at file scope are not allowed to.

In C you'll either need to use a non-standard macro (such as M_PI in GCC), create your own appropriate macro or literal (Ned Batchelder has done the hard part for you), or initialize it in your own function at an appropriately early enough time.

Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 4
    I'm being downvoted over a semantic detail about constant expressions for file scope variables and this post has 3 votes and defines `PI` to be 6.23. – Ben Jackson Jan 27 '12 at 22:22
  • @Ben: Yup - a bit embarrassing on the typo here (fixed it). FWIW, I upvoted your answer - I assumed the downvotes on it were because `M_PI` doesn't 'just work' on MSVC. – Michael Burr Jan 27 '12 at 22:36
  • @Ben : Stating that constants must be evaluated at compile-time in C++ is not a semantic detail, it's merely wrong. – ildjarn Jan 31 '12 at 00:56
  • @ildjarn: Since my answer got accepted I encourage anyone to edit it to be correct/precise. – Ben Jackson Jan 31 '12 at 01:38
2
#include <math.h>

const double PI = M_PI;

You can't call a function for a global const double because the constant needs to be evaluated at compile time. At runtime atan() could be anything. You could arrange for it to be called once at startup, but using an actual PI constant that's already available is better.

(actually using M_PI directly would also be good)

EDIT: It took many comment upvotes and re-reading my own answer over a year later to see why people were up in arms about my statement about constants. I was jumping over a step: As everyone is saying you can initialize const double at runtime just as easily as double. However, if you are using a global variable (instead of a constant expression) to store pi you will defeat some optimization opportunities. Some experiments with gcc suggest this isn't even as bad as I thought, which suggests a whole new question...

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
0

How about assembly language ?

fldpi

It is just alternative using Floating-Point Instruction