Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to test a float for 0.0 equality?

I know it's dangerous to test floats for equality due to precision errors but is it safe to test for zero? I can think of some cases, for example in optimizing special cases in algorithms, where you would want to do this. The question is regarding floats but I would assume the answer also applies to doubles as well.

Consider the following code:

float factor = calculateFactor();
if(factor != 0.0f)
    applyComplexAlgorithm(factor);
like image 432
Emil Eriksson Avatar asked Dec 20 '11 22:12

Emil Eriksson


People also ask

Is it safe to compare float to zero?

No, it is not OK. So-called denormalized values (subnormal), when compared equal to 0.0, would compare as false (non-zero), but when used in an equation would be normalized (become 0.0). Thus, using this as a mechanism to avoid a divide-by-zero is not safe. Instead, add 1.0 and compare to 1.0.

Is it safe to use the == operator for verifying is two float variables are equal?

Avoid using operator== and operator!= to compare floating point values if there is any chance those values have been calculated.

Does == work for floats Java?

According to this java. sun page == is the equality comparison operator for floating point numbers in Java. Java has a defined behavior for floats. The term used in the IEEE-754 standard is “significand,” not “mantissa.” The leading bit of the significand is 1 only if the exponent field is 1-254.


3 Answers

It is safe in the sense that if the value is set explicitly to 0.0f, it will return true there.

It is NOT safe in the sense that you should not expect that the value resultant from calculations will be exactly 0.0f.

So you're really using 0.0f as a special magic value of sorts, not as a real comparison against zero.

like image 145
supermem613 Avatar answered Nov 11 '22 20:11

supermem613


No, it's not safe, because the calculation in calculateFactor() will probably not result in 0.0 even through it arithmetically should. A trivial example: (0.4-0.1)-0.3 when done using double results in 5.551115123125783e-17

like image 24
Michael Borgwardt Avatar answered Nov 11 '22 21:11

Michael Borgwardt


It's certainly safe, but you do have to consider what it means for your algorithms. If your algorithm uses factor as a divisor (and doesn't check for divide-by-zero itself), then yes, it's perfectly reasonable to check for factor != 0.0f before calling applyComplexAlgorithm(factor).

Now, whether or not you should be checking for a value less than some epsilon before using factor, is totally up to what your code means and cannot be determined in isolation with the code you've provided.

If (as you alluded to in another comment) you want to use the special value 0.0f as a sentinel value that means something specific (such as the inability to calculate a factor), then yes, it's absolutely safe to compare using ==. For example, the following code's use of 0.0f is deterministic and is never subject to any kind of roundoff error:

float calculateFactor()
{
    int phase = moon_phase();
    if (phase == FULL) {  // whatever special case requires returning 0.0f
        return 0.0f;
    } else {
        return 1.0 + (phase * phase); // something that is never 0.0f
    }
}

float factor = calculateFactor();
if(factor != 0.0f)
    applyComplexAlgorithm(factor);
like image 28
Greg Hewgill Avatar answered Nov 11 '22 21:11

Greg Hewgill