Thomas O
Thomas O

Reputation: 6220

Compare a floating point number to zero

I want to check if an IEEE754 32-bit number has the value of exactly 0.0f (it will occasionally be set to it.) Accumulation errors will be nil as the data will be frequently updated from a sensor. My processor has no hardware FPU, so operations are done in a fairly fast software library. However, it's still hundreds of cycles for things like add, subtract and compare.

So I was wondering why my compiler does this:

240:                 if(p_viewer->roll != 0.0f)
 03FBC  B81160     mul.uu w2,#0,w2
 03FBE  900A2E     mov.w [w14+20],w4
 03FC0  900064     mov.w [w4+12],w0
 03FC2  9000F4     mov.w [w4+14],w1
 03FC4  07E91F     rcall __nesf2
 03FC6  E00000     cp0.w w0
 03FC8  320054     bra z, 0x004072

__nesf2 apparently compares two floating point numbers. Why doesn't it just do a compare against 0.0f in integer form, which is 0x00000000? Is there some reason it doesn't do this or is it just a missed optimisation opportunity?

My compiler is MPLAB C30, a version of GCC v3.23.

Upvotes: 5

Views: 2875

Answers (4)

user411313
user411313

Reputation: 3990

To check against 0.0f you don't need IEEE stuff, like:

int isFloatNull(float f)
{
  static float i;
  return !memcmp(&i,&f,sizeof i);
}

Upvotes: 0

Johan Kotlinski
Johan Kotlinski

Reputation: 25739

It is a missed optimization opportunity. 0.f is a special case since it has to do a compare with -0.f and 0.f. But still it would be faster to compare as ints.

Why is it not optimized? I would wager that it is an integration problem. Stuff like this usually falls between chairs. The people who have the task to put together the platform SDK pick a compiler (gcc), a software float library, and manage to glue it together in the best way they can. This works OK in the general case, and there is little motivation for improvement, since software floats generally are super slow anyway. The worst part is not comparison, but all the other stuff.

Simply put, if you have software floats, there is no point in using them if you need performance. Use fixed point for that.

Upvotes: 1

Stephen Canon
Stephen Canon

Reputation: 106187

Because -0.0f also compares equal to 0.0f, as required by the IEEE-754 standard.

You could replace the call with a comparison against the integer representations of both -0 (0x80000000) and +0, if this is a major performance issue. (Or better still, mask the sign bit and compare against 0.0f).

Upvotes: 7

Darron
Darron

Reputation: 21628

If this is a IEEE floating point implementation it has to take into account signalling NAN's.

You may not care about that, but the compiler doesn't know that.

Upvotes: 1

Related Questions