I do understand why we have this in standard headers:
#define M_PI 3.14159265358979323846 // pi
However, I don't see much benefit in having these:
#define M_PI_2 1.57079632679489661923 // pi/2
#define M_PI_4 0.785398163397448309616 // pi/4
#define M_1_PI 0.318309886183790671538 // 1/pi
#define M_2_PI 0.636619772367581343076 // 2/pi
Is there any advantage in using these instead of M_PI/2
, M_PI/4
, 1/M_PI
and 2/M_PI
in actual code? (In 2020 and beyond?)
Aren't the spelled-out expressions much more readable?
I'm asking for a couple of reasons really.
Firstly, one day I accidentally mixed up M_PI_2
and M_2_PI
(and maybe even 2 * M_PI
). Took a while to figure out something was wrong, and after that took another while to find out what exactly was the root cause. Still think it's not super obvious what M_PI_2
and M_2_PI
mean, if you are just reading code using them and don't see the definitions. And why should I memorize something like that? So, is it safe to say that using these definitions is actually an anti-pattern that degrades code readability?
Secondly, having these definitions available may still be an issue, e.g. in Windows (Visual C++). Instead of defining all these, I'd prefer to define only M_PI
, and then say M_PI/2
and not M_PI_2
in the code. Is there something I'm missing?
Because 2 and 4 are powers of two, M_PI_2 and M_PI_4 really are redundant and 100% equivalent to M_PI/2 and M_PI/4. However, M_1_PI is not necessarily equivalent to 1/M_PI; the latter has two roundings (approximation of pi, then inexact division) rather than just one (approximation of 1/pi). R.. GitHub STOP HELPING ICE
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.
None of these constants are part of the C or C++ standards. Rather they are part of the POSIX standard. In case of C++, starting with C++20, these constants will be standardized in std::numbers (at least pi and 1/pi). Because 2 and 4 are powers of two, M_PI_2 and M_PI_4 really are redundant and 100% equivalent to M_PI/2 and M_PI/4.
Btw, it's true that M_PI is not a standard but there's almost an implicit convention that it's declared in cmath in all platforms. This basically makes the event of clash in user code very unlikely, since a Windows user should use in its own code cmath and at the same time redefine M_PI as well. Is there any other possibility I don't see right now?
Because 2 and 4 are powers of two, M_PI_2
and M_PI_4
really are redundant and 100% equivalent to M_PI/2
and M_PI/4
. However, M_1_PI
is not necessarily equivalent to 1/M_PI
; the latter has two roundings (approximation of pi, then inexact division) rather than just one (approximation of 1/pi).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With