views:

2317

answers:

10

Can I compare a floating-point number to an integer?

Will the float compare to integers in code?

float f;     // f has a saved predetermined floating-point value to it  
if (f >=100){__asm__reset...etc}

Also, could I...

float f;
int x = 100;
x+=f;

Sorry, I don't have a lot of experience using floating point. But ultimately I have to use the floating point value f received from an attitude reference system to adjust a position value x that controls a PWM signal to correct for attitude.

-Thanks

A: 

Yeah, it'll work fine. Specifically, the int will be converted to float for the purposes of the conversion. In the second one you'll need to cast to int but it should be fine otherwise.

Promit
+2  A: 

The first one will work fine. 100 will be converted to a float, and IEE754 can represent all integers exactly as floats, up to about 223.

The second one will also work but will be converted into an integer first, so you'll lose precision (that's unavoidable if you're turning floats into integers).

paxdiablo
Thanks, so that means if f = 1.0162 it would be int f == 1, so I would just have to scale it, f*=1000; so int f == 1016 to retain precision?
sevenboarder
You can't represent all integers exactly as float. Not with float's 24-bit mantissa. If it were double, yes, but not float :)
Joey
@Johannes, you're right, I'm mis-remembering a question I answered recently, updated to fix.
paxdiablo
A: 

LHS defines the precision, So if your LHS is int and RHS is float, then this results in loss of precision.

Also take a look at FP related CFAQ

Alphaneo
A: 

Yes, and sometimes it'll do exactly what you expect.

As the others have pointed out, comparing, eg, 1.0 == 1 will work out, because the integer 1 is type cast to double (not float) before the comparison.

However, other comparisons may not.

Charlie Martin
+1  A: 

Yes, you can compare them, you can do math on them without terribly much regard for which is which, in most cases. But only most. The big bugaboo is that you can check for f<i etc. but should not check for f==i. An integer and a float that 'should' be identical in value are not necessarily identical.

Kim Reece
+1  A: 

Can you compare a float and an integer, sure. But the problem you will run into is precision. On most C/C++ implementations, float and int have the same size (4 bytes) and wildly different precision levels. Neither type can hold all values of the other type. Since one type cannot be converted to the other type without loss of precision and the types cannot be native compared, doing a comparison without considering another type will result in precision loss in some scenarios.

What you can do to avoid precision loss is to convert both types to a type which has enough precision to represent all values of float and int. On most systems, double will do just that. So the following usually does a non-lossy comparison

float f = getSomeFloat();
int i = getSomeInt();
if ( (double)i == (double)f ) { 
   ...
}
JaredPar
I think you want ">=" (to match the original question) and not "==". Testing for exact equality of floating-point numbers is almost always a bad idea.
Michael Carman
+3  A: 

Since you've identified yourself as unfamiliar with the subtleties of floating point numbers, I'll refer you to this fine paper by David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic (reprint at Sun).

After you've been scared by that, the reality is that most of the time floating point is a huge boon to getting calculations done. And modern compilers and languages (including C) handle conversions sensibly so that you don't have to worry about them. Unless you do.

The points raised about precision are certainly valid. An IEEE float effectively has only 24 bits of precision, which is less than a 32-bit integer. Use of double for intermediate calculations will push all rounding and precision loss out to the conversion back to float or int.

RBerteig
+1 for the WECSSKAFPA link, that saved me from surfing it up. :)
unwind
I gave the paper a skim, I might put that off till later... haha
sevenboarder
It is a bit heavy on the math... but you can skim past all the proofs and get the important points. The big important point is just that it isn't always simple...
RBerteig
I love the "unless you do" bit :-)
paxdiablo
Thanks, Pax. I was trying for reassuring without technically lying...
RBerteig
A: 

Mixed-mode arithmetic (arithmetic between operands of different types and/or sizes) is legal but fragile. The C standard defines rules for type promotion in order to convert the operands to a common representation. Automatic type promotion allows the compiler to do something sensible for mixed-mode operations, but "sensible" does not necessarily mean "correct."

To really know whether or not the behavior is correct you must first understand the rules for promotion and then understand the representation of the data types. In very general terms:

  • shorter types are converted to longer types (float to double, short to int, etc.)
  • integer types are converted to floating-point types
  • signed/unsigned conversions favor avoiding data loss (whether signed is converted to unsigned or vice-versa depends on the size of the respective types)

Whether code like x > y (where x and y have different types) is right or wrong depends on the values that x and y can take. In my experience it's common practice to prohibit (via the coding standard) implicit type conversions. The programmer must consider the context and explicitly perform any type conversions necessary.

Michael Carman
A: 

Apologies for re-opening this a few months later, but I just wanted to double-check on something.

Charlie mentioned above, As the others have pointed out, comparing, eg, 1.0 == 1 will work out, because the integer 1 is type cast to double (not float) before the comparison.

Is it the compiler doing this casting? I guess where I'm not clear is how this is happening if there isn't a cast included in the line of code.

A: 

About that, the notation 1.0 is of type double so the comparison is made in double by type promotion rules like said before. 1.f or 1.0f is of type float and the comparison would have been made in float. And it would have worked as well since we said that 2^23 first integers are representible in a float.

Lightness1024