June 23, 2004

Integer log of subnormal IEEE float

Last Sunday, Sean A. Irvine suggested that I add code for handling subnormals in my method to find the integer log base 2 of a 32-bit IEEE float.  He suggested the following, which doesn't terminate when the input, v, is 0:
const float v; // compute c = int(log2(v))
int x = *(int *)&v;
int c = x >> 23;
if (c == 0) {
   // handle subnormals
   while ((x & 0x400000) == 0) {
     x <<= 1;
     c--;
   }
}
return c - 127;
I didn't like the idea that the code would loop indefinately, so I replaced the loop, which computes the integer log base 2 of the mantissa, with a version that computes it via table lookup; it is slightly modified from the general case, since we need only deal with 23 bits.  It should be faster than the code above.
const float v;   // find int(log2(v)), where v > 0.0 && finite(v)
const int x = *(int *) &v; 
int c = x >> 23; // c gets the result;

if (c)
{
  c -= 127;
}
else
{ // subnormal, so recompute using mantissa: c = intlog2(x) - 149;
  register unsigned int t; // temporary
  // Note that LogTable256 was defined earlier
  if (t = x >> 16)
  {
    c = LogTable256[t] - 133;
  }
  else
  {
    c = (t = x >> 8) ? LogTable256[t] - 141 : LogTable256[x] - 149;
  }
}
Posted by seander at June 23, 2004 10:43 PM
Comments