Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating Point, how much can I trust less than / greater than comparisons?

Let's say I have two floating point numbers, and I want to compare them. If one is greater than the other, the program should take one fork. If the opposite is true, it should take another path. And it should do the same thing, if the value being compared is nudged very slightly in a direction that should still make it compare true.

It's a difficult question to phrase, so I wrote this to demonstrate it -

float a = random();
float b = random();  // always returns a number (no infinity or NaNs)

if(a < b){
    if( !(a < b + FLOAT_EPISILON) ) launchTheMissiles();
    buildHospitals();

}else if(a >= b){
    if( !(a >= b - FLOAT_EPISILON) ) launchTheMissiles();
    buildOrphanages();

}else{
    launchTheMissiles();  // This should never be called, in any branch
}

Given this code, is launchTheMissiles() guaranteed to never be called?

like image 563
Anne Quinn Avatar asked Mar 12 '13 23:03

Anne Quinn


People also ask

Are floating point comparisons reliable?

The floating point comparison is not similar to the integer comparison. To compare two floating point values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.

Why do we never use == to compare floating point numbers?

Because floating point arithmetic is different from real number arithmetic. Bottom line: Never use == to compare two floating point numbers. Here's a simple example: double x = 1.0 / 10.0; double y = x * 10.0; if (y !=

How do you test the equality of a float?

The compare() method of Float Class is a built-in method in Java that compares the two specified float values. The sign of the integer value returned is the same as that of the integer that would be returned by the function call. Parameters: The function accepts two parameters: f1: The first float value to be compared.


2 Answers

If you can guarantee that a and b are not NaNs or infinities, then you can just do:

if (a<b) {
    …
} else {
    …
}

The set of all floating point values except for infinities and NaNs comprise a total ordering (with a glitch with two representations of zero, but that shouldn't matter for you), which is not unlike working with normal set of integers — the only difference is that the magnitude of intervals between subsequent values is not constant, like it is with integers.

In fact, the IEEE 754 has been designed so that comparisons of non-NaN non-infinity values of the same sign can be done with the same operations as normal integers (again, with a glitch with zero). So, in this specific case, you can think of these numbers as of “better integers”.

like image 164
liori Avatar answered Oct 07 '22 00:10

liori


Short answer, it is guaranteed never to be called.

If a<b then a will always be less than b plus a positive amount, however small. In which case, testing if a is less than b + an amount will be true.

The third case won't get reached.

like image 38
Chris K Avatar answered Oct 06 '22 22:10

Chris K