9

So I often see something like this:

#define gf_PI  f32(3.14159265358979323846264338327950288419716939937510)
#define gf_PIhalf  f32(3.14159265358979323846264338327950288419716939937510 * 0.5)

This means that half PI value is calculated every time I use gf_PIhalf in my code, right?
Wouldn't it be better to literally write the value of half PI instead?

Wouldn't it be even better to do the following:

#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
const float gf_PIHalf = gf_PI * 0.5f;    // PIHalf is calculated once

Finally wouldn't it be best to do it like this (and why it doesn't seem to be a common practice):

const float gf_PI = 3.14159265358979323846264338327950288419716939937510;
const float gf_PIHalf = gf_PI * 0.5f;
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jaho
  • 4,852
  • 6
  • 40
  • 66
  • 1
    do you really care if your program does one multiplication more ? is it really that critical ? – Smash Feb 28 '13 at 22:00
  • This is a great question. I once asked a similar question about memory constraints and efficiency, and I think the standard answer I received was similar to "Honestly, at this rate, it doesn't matter. It's such a small amount of data that the ratio of efficiency doesn't take much of a hit." I think in this case, You'll find that the efficiency of the program doesn't necessarily suffer VS. the idea that you get a re-calculation that you can trust every time. If you're confident in the arithmetic, I'd go for pure efficiency. – plast1K Feb 28 '13 at 22:01
  • See, a good compiler optimizes away [even a complete mess like this](http://stackoverflow.com/questions/15114140/writing-binary-number-system-in-c-code/15114188#15114188) into one constant... –  Feb 28 '13 at 22:01
  • @Smash: Well, it's not likely to become a bottleneck but if the multiplication operation would in fact occur every time and it would be used in a critical loop called very often then I don't see a reason why not to make sure it doesn't occur by using one of the other solutions. – jaho Feb 28 '13 at 22:09
  • @plast1K: It's a constant. Recalculating it every time doesn't make me trust it anymore. – jaho Feb 28 '13 at 22:10

2 Answers2

11

This means that half PI value is calculated every time I use gf_PIhalf in my code, right?

Nope, not likely.

You can reasonably count on your compiler to do that multiplication at compile time, not runtime.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
3

Your conclusions are somewhat right, except that the #define version will almost definitely resolve in compile time and the bit about types const globals being uncommon practice. They are common practice in modern good code. #defines are all but dead for this use. The best practice is to define your file scope globals in an unnamed namespace:

namespace
{
    const float g_SomeGlobal = 123.456f;
}

This prevents anyone outside of your translation unit from being able to 'see' g_SomeGlobal.

David
  • 27,652
  • 18
  • 89
  • 138