Be very careful with floating point numbers
Since it keeps coming up, I'll say again, never depend on floating point equality checks (or transitivity). As an example, I just ran into a problem with domino caused by C++ code which looked like: float min=big_number; loop over things: if (thing.get_value() < min) min= thing.get_value()
loop over things again: if (thing.get_value() == min) return thing;
Code like this can fail if: - the type of thing.get_value() is not exactly the same as the type of min - or thing.get_value() performs some computations and the compiler decides to inline them - or for whatever other reason, thing.get_value() is never written to main memory
The reason is that on intel chips, floating point values are stored as 32 bit, 64 bit or 80 bit values depending on what the compiler feels like doing. They are only truncated into the specified 32 bit (float) or 64 bit (double) values when stored as the appropriate value type in cache or memory or when copied to a different type of register. If one copy of a value is truncated to a 32 bits or 64 bits by being moved, then it is no longer equal to its old value.
In this case the fix is trivial: just combine the two loops and keep track of the min element as you go along. Other times you will have to jump through more hoops.
Perhaps a useful rule of thumb: if you ever find yourself writing "==" with floating point numbers, stop and think: what you are doing is probably wrong. ;)
Ben
Or, more generally, never count on two floating point operations to return consistent answers.
Recently someone posted to one of the C++ newsgroups about a crash while sorting points based on the distance from another point. The sorting was done by, at each comparison, computing the distance of the two points being compared to the reference point and then comparing this sorted distance. Unfortunately, the results of this comparison depended on details such as whether the compiler chose to store the result of the computation in an 80 bit or 64 bit register (since truncation could change the order of two values) and so the comparisons did not form a total ordering on the points and as a result sorting would bomb out with some compilers and some optimization settings.
On Mar 25, 2009, at 9:11 PM, Ben Webb wrote:
> Perhaps a useful rule of thumb: if you ever find yourself writing "==" > with floating point numbers, stop and think: what you are doing is > probably wrong. ;) > > Ben > -- > ben@salilab.org http://salilab.org/~ben/ > "It is a capital mistake to theorize before one has data." > - Sir Arthur Conan Doyle > _______________________________________________ > IMP-dev mailing list > IMP-dev@salilab.org > https://salilab.org/mailman/listinfo/imp-dev
participants (2)
-
Ben Webb
-
Daniel Russel