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