problem with float comparison

Discussion to talk about software related topics only.
Post Reply
mmk-tsm
Posts: 33
Joined: Mon Jan 05, 2009 9:22 am

problem with float comparison

Post 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.
User avatar
pbreed
Posts: 1088
Joined: Thu Apr 24, 2008 3:58 pm

Re: problem with float comparison

Post 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))
User avatar
pbreed
Posts: 1088
Joined: Thu Apr 24, 2008 3:58 pm

Re: problem with float comparison

Post by pbreed »

This is not a "Netburner" thing its a "C" language thing.
Same issues happen for & && etc...

Paul
mmk-tsm
Posts: 33
Joined: Mon Jan 05, 2009 9:22 am

Re: problem with float comparison

Post by mmk-tsm »

Thanks, Paul.
greengene
Posts: 164
Joined: Wed May 14, 2008 11:20 am
Location: Lakeside, CA

Re: problem with float comparison

Post 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
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: problem with float comparison

Post by tod »

Is this somehow a different question? See Paul's reply and put in the explicit parentheses.
greengene
Posts: 164
Joined: Wed May 14, 2008 11:20 am
Location: Lakeside, CA

Re: problem with float comparison

Post 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.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: problem with float comparison

Post 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.
Post Reply