28

This is a really simple question: Why are there predefined constants for pi, pi/2, pi/4, 1/pi and 2/pi but not for 2*pi? Is there a deeper reason behind it?

This question is not about the whole pi vs tau debate. I am wondering if there is a technical reason for implementing certain constants but not others. I can think of two possibilities:

  1. Avoiding rounding errors.
  2. Avoiding runtime divisions which might be more expensive.
hanno
  • 6,401
  • 8
  • 48
  • 80
  • 4
    What would you want to use `2*pi` for? Most trigonometric functions, for example, "repeat" after `2*pi` (have a translational symmetry of `2*pi`). (More formally, for example, `sin(a) = sin(b)` if `a = b (mod 2*pi)`.) This makes it useless to add or subtract `2*pi` to or from numbers you use as arguments to these functions. – MvanGeest Nov 17 '12 at 00:58
  • PI, HALF_PI ok, but what is name of 2/pi constant? – weston Nov 17 '12 at 01:00
  • 9
    @MvanGeest There are so many use cases. How about normal distributions, fast Fourier transforms, Cauchy's integrals to start with? – hanno Nov 17 '12 at 01:05
  • 3
    Why didn't they also define `3*pi`, `12*pi`, and `-4*pi`? This question is asking for a discussion that has no definitive answer unless one of the original authors of `math.h` happens to stop by to answer it. Sorry, but voting to close as not constructive; the [FAQ](http://stackoverflow.com/faq) specifically mentions discussion and speculation type questions as being inappropriate for the design here. – Ken White Nov 17 '12 at 01:07
  • @hanno: There may be *many* use cases, but as I tried to demonstrate, *probably* less than for the other constants. Whether that or something else was the reason for the decision will, as Ken White remarks, remain uncertain until the original authors chime in ;) – MvanGeest Nov 17 '12 at 01:10
  • 1
    I disagree with you. There are people who have heated discussions about tau (=2*pi) vs pi. My intention was *not* to start this discussion here all over again. However, I still hope there might be a simple answer to my original question. Maybe multiplying pi by 2 gives the exact answer within floating point precision whereas the other constants would give an error at the last digit? – hanno Nov 17 '12 at 01:13
  • 3
    @Ken: or one of the authors has answered it elsewhere, and someone can find that answer and refer to it. I really don't get why people think standard rationale questions are unanswerable -- the meetings are (somewhat) minuted. – Steve Jessop Nov 17 '12 at 01:19
  • Of course you disagree; if you agreed, you wouldn't have posted the question in the first place. :-) My close vote was based on my opinion of the question's being proper or not, and I don't feel it is for the reasons I stated. I was polite enough to explain why (which there was no obligation to provide). Maybe multiplying `pi` by other numbers that give "the exact answer within floating point precision" should have been defined as well; maybe the decision was made just because no one saw the need to define `2*pi`. Who knows? And who really cares? If you need it, define it. – Ken White Nov 17 '12 at 01:20
  • 7
    I care because I type this constant approximately 100 times a day. – hanno Nov 17 '12 at 01:26
  • 2
    May not be about tau vs pi, but thanks for that link, I am definitely using tau from now on! – weston Nov 17 '12 at 10:12

2 Answers2

5

Is 2*M_PI so hard to write?

Seriously though, once upon a time, when people worried about simple compilers that might not do constant folding and division was prohibitively expensive, it actually made sense to have a constant PI/2 rather than risk a runtime division. In our modern world, one would probably just define M_PI and call it a day, but the other variants live on for backwards compatibility.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
4

This is just my guess.

I suppose that these constants are related to the implementations of different functions in the math library:

ck@c:~/Codes/ref/glibc/math$ grep PI *.c
s_cacos.c:  __real__ res = (double) M_PI_2 - __real__ y;
s_cacosf.c:  __real__ res = (float) M_PI_2 - __real__ y;
s_cacosh.c:                    ? M_PI - M_PI_4 : M_PI_4)
...
s_clogf.c:      __imag__ result = signbit (__real__ x) ? M_PI : 0.0;
s_clogl.c:      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
ck@c:~/Codes/ref/glibc/math$ 

M_PI, M_PI_2, and M_PI_4 show up quite often but there's no 2.0 * M_PI. So to Hanno's original question, I think MvanGeest is right --- 2π is just not that useful, at least in implementing libm.

Now about M_PI_2 and M_PI_4, their existences are well justified. The documentation of the GNU C library suggests that "these constants come from the Unix98 standard and were also available in 4.4BSD". Compilers were not that smart back at that time. Typing M_PI/4 instead of M_PI_4 may cause an unnecessary division. Although modern compilers can optimize that away (gcc uses mpfr since 2008 so even rounding is done correctly), using numeric constants is still a more portable way to write high performance code.

C.K.
  • 66
  • 2