-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use better math constants #1447
base: master
Are you sure you want to change the base?
Conversation
We can discuss the opportunity to use more precision if we want to. |
#define M_SQRT2 1.414213562f The accuracy is a little unusual. |
Let's use names that are not the same as the C ones so we don't have to deal with ifdef bullshit. How about |
For a random float value 7 digits is often enough, but some need up to 9 digits to get back the float value which is the closest to the number you want to represent. |
Besides annoying ifdef stuff, using the C library names is also bad because of the type mismatch. The C library ones are expected to be floats. So a 3rd-party library using these could get our definitions and end up with a value with the wrong type and less precision than expected. Conversely, when the C library does provide them we will end up using double instead of float in our own code when we didn't want to. |
Oh, right, |
9b53faf
to
dd52bb4
Compare
I added some I wrote a generator for them in Python using For completeness I added one constant for every one defined by GNU or I added some constants that weren't defined in either GNU or I also turned I actually wonder if all There is no one usage of any For the naming scheme, I followed the way it was done in The exception is For constants from functions that have more than one argument (something As suggested, I added a I did some search for hardcoded constant values, and I replaced all the |
There was at least two comments saying to include headers in specific order to avoid getting in troubles with |
The generator script is not run at build time, as we only need to run it when we add a new named constant. The one adding such new named constant can run the script and commit the regenerated header. |
src/common/math/Constant.h
Outdated
constexpr float divpi_4_f = .785398163f; // π÷4 M_PI_4f | ||
constexpr float divpi_90_f = .034906585f; // π÷90 | ||
constexpr float divpi_180_f = .017453292f; // π÷180 | ||
constexpr float divpi_360_f = .008726646f; // π÷360 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ones less than 0.1 seem to have less precision. You should do like %.9g
not %.9f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's me who actually stripped that to have nice aligned columns! 🤦♀️️ I forgot I could aligne the numbers to the right. Now fixed.
@@ -218,8 +218,8 @@ bool R_LoadMD3( model_t *mod, int lod, const void *buffer, const char *modName ) | |||
v->xyz[ 1 ] = LittleShort( md3xyz->xyz[ 1 ] ) * MD3_XYZ_SCALE; | |||
v->xyz[ 2 ] = LittleShort( md3xyz->xyz[ 2 ] ) * MD3_XYZ_SCALE; | |||
|
|||
lat = (latLng >> 8) * (2.0f * M_PI / 255.0f); | |||
lng = (latLng & 255) * (2.0f * M_PI / 255.0f); | |||
lat = (latLng >> 8) * (Math::mul2_pi_f / 255.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would rather use 2.0f * Math::pi_f
. "mul2_pi" is incomprehensible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately I cannot do Math::2pi_f
. 😭️🤣️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the ones that are just a power of 2 times some other constant should be removed. Especially if they are not in any of the other math libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with those names, mul2_pi
just means mul(2, pi)
so 2π
, like div2_pi
means div(2, pi)
so 2/π
, this is consistant. It matches prefixed writing and function calling (which uses a prefixed convention by the way).
Also, this constant is used very often, and some math libraries like GLM also provides a dedicated symbol for it as well, named glm::two_pi()
.
That GLM naming looks interesting at first glance but it quickly goes out of hands, for example with inv(mul(2, pi)
so 1/2π
, I named it inv_mul2_pi
but GLM named one_over_two_pi
…
I'm not surprised GLM doesn't define a constant for π/360
, as what I named divpi_360
, GLM would name it pi_over_three_hundred_and_sixty
… 🤦♀️️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also see that GLM naming convention is following infix convention, which is also calling for trouble.
So I'm fine with the convention I propose, it's the best I could find: better than GLM, and very close to standard C++ names.
I'm also fine with those constants being defined to begin with, they are common enough for other math libraries to define them and define more than what GCC and the C++ standard do. Actually GLM define some constants I haven't defined, like 4/π
or 3/2π
…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For those I would just use normal multiplication and delete the 2*π constants :S
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For those I would just use normal multiplication and delete the 2*π constants. Only downside is that in a few case one would want to put parethesis if after a divide sign, but that should be rare and easy enough. And for performance concerns I'm really not worried about it, see my main comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That GLM naming looks interesting at first glance but it quickly goes out of hands, for example with
inv(mul(2, pi)
so1/2π
, I named itinv_mul2_pi
but GLM namedone_over_two_pi
…
The GLM naming is better since it follows mathematical terminology, so I would actually be able to tell what it means without having to go read the source.
Actually GLM define some constants I haven't defined, like
4/π
or3/2π
…
WTF
c8e5882
to
64b4977
Compare
I created the |
64b4977
to
8291807
Compare
8291807
to
2dc94f9
Compare
While making use of the new constants, the compiler type check insulted me because of type mismatches with double hardcoded values, that reminds me may have to check for all the useless double hardcoded values (like |
I've checked the code somewhat quickly, that's ok with me. I would would argue that this is a bit overkill though ^_^' Especially for the constants that do things like 2/3: since we enable agressive optimisations (that are not allowed in IEE-754) that allow reordering the operations. So gcc can already turn I also did change plenty of constants to floats back in the day. I think those are helpful. Good that you did catch some more. |
9a8ae41
to
d51782d
Compare
We have this:
So we do:
I suggest we get this:
So we can do instead:
See also: