What would be the most efficient way to compare two double
or two float
values?
Simply doing this is not correct:
bool CompareDoubles1 (double A, double B) { return A == B; }
But something like:
bool CompareDoubles2 (double A, double B) { diff = A - B; return (diff < EPSILON) && (-diff < EPSILON); }
Seems to waste processing.
Does anyone know a smarter float comparer?
Floats are faster than doubles when you don't need double's precision and you are memory-bandwidth bound and your hardware doesn't carry a penalty on floats. They conserve memory-bandwidth because they occupy half the space per number.
A float uses less memory than a double, so if you don't need your number to be the size of a double, you might as well use a float since it will take up less memory. Just like you wouldn't use a bus to drive yourself and a friend to the beach... you would be far better off going in a 2 seater car.
They are: Bitwise comparison. Direct ("exact") IEEE-754 comparison. Absolute margin comparison.
Be extremely careful using any of the other suggestions. It all depends on context.
I have spent a long time tracing a bugs in a system that presumed a==b
if |a-b|<epsilon
. The underlying problems were:
The implicit presumption in an algorithm that if a==b
and b==c
then a==c
.
Using the same epsilon for lines measured in inches and lines measured in mils (.001 inch). That is a==b
but 1000a!=1000b
. (This is why AlmostEqual2sComplement asks for the epsilon or max ULPS).
The use of the same epsilon for both the cosine of angles and the length of lines!
Using such a compare function to sort items in a collection. (In this case using the builtin C++ operator == for doubles produced correct results.)
Like I said: it all depends on context and the expected size of a
and b
.
BTW, std::numeric_limits<double>::epsilon()
is the "machine epsilon". It is the difference between 1.0 and the next value representable by a double. I guess that it could be used in the compare function but only if the expected values are less than 1. (This is in response to @cdv's answer...)
Also, if you basically have int
arithmetic in doubles
(here we use doubles to hold int values in certain cases) your arithmetic will be correct. For example 4.0/2.0 will be the same as 1.0+1.0. This is as long as you do not do things that result in fractions (4.0/3.0) or do not go outside of the size of an int.
The comparison with an epsilon value is what most people do (even in game programming).
You should change your implementation a little though:
bool AreSame(double a, double b) { return fabs(a - b) < EPSILON; }
Edit: Christer has added a stack of great info on this topic on a recent blog post. Enjoy.
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