When There is No π

Reader Chris pointed out a fun and common C language inconsistency in last week’s Lesson: The constant M_PI isn’t always available. It’s not defined as part of the C standard, which means your compiler may lack this handy shortcut, located in the math.h header file. What to do, what to do?

One of the problems with “standards” in the computer industry is that they are anything but standards. Some exist historically, but are never officially declared. And then you have Microsoft, which declares industry standards that only Microsoft adheres to. It’s a mess.

With C, the primary standard is ANSI. The most recent versions are C99 (1999) and C11 (2011). The GNU standard also exists, implemented in the ubiquitous gcc compiler. Going back further is the K&R standard, based on C as documented in Kernighan and Ritchie’s book, The C Programming Language, aka “the manual.”

In the GNU standard, many constants are declared in the math.h header file, including M_E, M_LOG10E, M_SQRT2, and M_PI.

The C99 standard doesn’t specify M_PI, neither does C11. Its absence doesn’t imply that it’s illegal to use the M_PI constant, just that a programmer shouldn’t assume that M_PI is available in all compilers.

To resolve this issue in your code, add the following preprocessor instructions in addition to including the math.h header file:

#ifndef M_PI
#define M_PI (3.14159265358979323846264338327950288)
#endif /* M_PI */

The #ifndef preprocessor directive resolves as TRUE when M_PI is unavailable. If so, the next line defines the constant. The #endif directive closes the statements. When M_PI is defined, the other two statements are skipped. (Click here to read more about preprocessor directives.)

It doesn’t hurt to add this type of checking for any constant you use, especially for code you plan on releasing into the wild.

Another problem exists when functions are available in some libraries but not others. For example, the random() function is available in clang, but not in gcc (at least the last time I checked). If you’re practicing on your own, overlooking what’s standard and what’s not is okay. But when you must write a program and distribute its source, ensure that you check for all possibilities, confirm what’s standard and what’s not, and provide resolutions in your code for what’s unavailable.

4 thoughts on “When There is No π

  1. “Reader Chris pointed out a fun and common C language inconsistency”

    I never said it was fun! In fact it’s quite annoying 🙂 I think it would be better if it was never there at all rather than sometimes there, then you would just need the #define instead of #ifndef & #endif as well.

    The standard library has a rand (not random) function which returns a random number between 0 and RAND_MAX:

    https://www.gnu.org/software/libc/manual/html_node/ISO-Random.html

    Incidentally, I read somewhere that the distribution of the digits of pi is more or less perfectly random, and can be used as the basis of generating random numbers. That would presumably not be secure though, because if someone realised how the numbers were generated they could predict them. Should be OK for stochastic/Monte Carlo type stuff though.

  2. I studied up on the pseudo-random number generating algorithms a long time ago and was thinking of presenting them here. Many of them are simple, some are really weird, but they must all be seeded or they can be predicted. Using the device’s clock is pretty much the accepted method, however using the clock timer as an index into π would add another level of randomness.

    Yeah, I think it’s fun!

Leave a Reply