Page 1 of 1

problem with float comparison

Posted: Tue Aug 16, 2011 3:54 am
by mmk-tsm
Hello all,
I have a problem with a float comparison, of the format
float fValue;
if(fValue < 0.04f || fValue > 2000.0f)
{
.....use default for fValue.
}

the fValue is a calibration parameter, read from EEPROM at start, all zeroes(4 bytes) in the float format I think, it displays as -422699897780557818927743415137991655424.0

I could not get my comparison to work and pick up this invalid value. What can or should I do to make it work?

Mike.

Re: problem with float comparison

Posted: Tue Aug 16, 2011 3:44 pm
by pbreed
You have an operator precedence problem.

with () to show the actual operator precidence...

if(fValue < (0.04f || fValue )> 2000.0f)

You need to add () whenever you are using | or || as the operator precedence is not obvious.

So

if((fValue < 0.04f )|| (fValue > 2000.0f))

Re: problem with float comparison

Posted: Tue Aug 16, 2011 3:45 pm
by pbreed
This is not a "Netburner" thing its a "C" language thing.
Same issues happen for & && etc...

Paul

Re: problem with float comparison

Posted: Wed Aug 17, 2011 1:20 am
by mmk-tsm
Thanks, Paul.

Re: problem with float comparison

Posted: Tue Aug 23, 2011 3:21 pm
by greengene
i'm kinda a newbie, but here's my example:

float fValue=1.0f;
if(fValue < 0.04f || fValue > 2000.0f)
puts("out of bounds#1");
fValue = -1.0f;
if(fValue < 0.04f || fValue > 2000.0f)
puts("out of bounds#2");
fValue = 3000.0f;
if(fValue < 0.04f || fValue > 2000.0f)
puts("out of bounds#3");

results in:
out of bounds#2
out of bounds#3

Re: problem with float comparison

Posted: Tue Aug 23, 2011 4:37 pm
by tod
Is this somehow a different question? See Paul's reply and put in the explicit parentheses.

Re: problem with float comparison

Posted: Thu Aug 25, 2011 12:24 pm
by greengene
i don't believe that the operator precedence interpretation that was proposed is correct.
i do agree using parentheses to remove ambiguity is preferrable.

however, my example demonstrates that the operator precedence is that the
inequality operators are evaluated before the logical operator.

Re: problem with float comparison

Posted: Fri Aug 26, 2011 11:32 am
by tod
Sorry, greenegene. I wasn't following that you were challenging the precedence. I think you are correct. I just looked up C and C++ operator precedence in a couple of places and they all show that < and > have higher precedence than ||. So I agree the problem isn't precedence.

I suspect the problem could be solved by reversing the logic. That is, look for value that is in range, not out of range. I say this because floating point numbers have some properties that can trap the unwary. Notably there is a value for positive zero, negative zero, and Not a Number (NaN). The biggest issue here would be NaN. Everything comparing a NaN returns false including NaN == NaN. This means if the uninitialized memory holds a value that evaluates to NaN the logic will always return false (in this case incorrectly indicating that the number is in range). If the logic is reversed to test for values WITHIN range the expression will return false, correctly indicating a value out of range. That said, I would have thought 4 bytes of zeros would have evaluated to positive zero but I will freely admit to not having verified that assumption against the IEEE 754 standard. I think a bug in an older version of the gcc compiler required special case comparisons against +0 and -0 but I think the more recent versions all do this automatically.

So my advice to mmk.
1. Always explicitly parenthesize (be kind to the maintenance programmer)
2. When working with floating point be VERY careful and always test for values in range.
3. When comparing floats or doubles consider whether you should do exact or approximate comparisons.