Reputation: 139
I was just writing some code for a fairly simple physics simulation program where the user could alter gravitational acceleration and I wanted to limit the minimum gravity value to some value (to prevent 0 and negative gravity).
I ended up with something like this:
if(g_accel > 0.1) {
g_accel -= 0.1;
}
Where g_accel is set to 1.0 at the start of the program. However it would still allow the user to go below 0.1 to a value something like 1.38778e-016. My solution to the problem was to instead check:
if(g_accel > 0.1+std::numeric_limits<double>::epsilon()) {
g_accel -= 0.1;
}
Aside from the use of magic constants, my problem is that I have no idea why this is necessary, and, furthermore, I don't really understand why epsilon() is useful or how/when it is used.
I was also looking at some code a moment ago that looked like this:
inline void Vector2D::Normalize()
{
double vector_length = this->Length();
if (vector_length > std::numeric_limits<double>::epsilon())
{
this->x /= vector_length;
this->y /= vector_length;
}
}
What's going on with std::numeric_limits::epsilon()?
Upvotes: 2
Views: 324
Reputation: 1310
From the cppreference page on std::numeric_limits<T>::epsilon
, std::numeric_limits<T>::epsilon()
returns the smallest such T that 1 + std::numeric_limits<T>:epsilon()
is not equal to 1. This value is only useful if std::numeric_limits<T>::is_integer()
returns false. The name for this value is the machine epsilon.
Because the representation of floating point numbers results in bigger gaps between representable numbers as the numbers get farther away from 0 on the number line, the return value of epsilon()
needs to be scaled to work with the result. Real Time Collision Detection by Christer Ericson describes some of the math behind the scaling. The recommendation he suggests in his book is that the epsilon value that should be used when performing floating point equality checks should be the square root of the machine epsilon.
Bruce Dawson's blog series, which I linked to above, is a great resource for learning about the complexities of floating point arithmetic. I highly recommend reading all of the posts in the series if you'd like to continue implementing physics simulations.
Upvotes: 3