Find integer log base 2 of a 32-bit IEEE float

From WikiCoder
 const float v; // find int(log2(v)), where v > 0.0 && finite(v) && isnormal(v)
 int c;         // 32-bit int c gets the result;
 
 c = *(const int *) &v;  // OR, for portability:  memcpy(&c, &v, sizeof c);
 c = (c >> 23) - 127;

The above is fast, but IEEE 754-compliant architectures utilize subnormal (also called denormal) floating point numbers. These have the exponent bits set to zero (signifying pow(2,-127)), and the mantissa is not normalized, so it contains leading zeros and thus the log2 must be computed from the mantissa. To accomodate for subnormal numbers, use the following:

 const float v;              // find int(log2(v)), where v > 0.0 && finite(v)
 int c;                      // 32-bit int c gets the result;
 int x = *(const int *) &v;  // OR, for portability:  memcpy(&x, &v, sizeof x);
 
 c = x >> 23;          
 
 if (c)
 {
   c -= 127;
 }
 else
 { // subnormal, so recompute using mantissa: c = intlog2(x) - 149;
   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;
   }
 }

References