Sorry about that, the function I am interested in is
\floor(\log_2(ix))
And I'm looking towards a more computational solution than
a large table lookup. I can not afford to store large tables. (At
most a few bytes...64/128 bytes space maybe at most).
In that case, the simple one:
int log2int(uint_type ix)
{
int i;
for (i = -1; ix; ix >>= 1)
++i;
return i;
}
will be much faster than converting to float etc. (and is portable
whatever the actual type of uint_type, as long as it's unsigned
integer of some form).
Doing a "binary chop" on it might be even faster but more convoluted
code (so it might actually work out slower for small values of ix, I
haven't timed them):
#include <limits.h>
int log2int(uint_type ix)
{
int shift = (sizeof(ix) * CHAR_BIT) / 2;
int val = 0;
if (ix == 0)
return -1;
while (ix && shift)
{
uint_type tmp = ix >> shift;
if (tmp)
{
val += shift;
ix = tmp;
}
else
{
shift /= 2;
}
}
return val;
}
Note that the initial value of 'shift' can be any positive value ypu
like (as long as it's greater than 0 and less than the number of bits in
uint_type), setting it to half the number of bits in uint_type is the
most efficient but if you don't want to include limits.h you could
hard-code it to 16 for instance.
(Both functions return -1 as an error value if ix is zero. In the first
that just "falls out" of the algorithm, the second tests explicitly for
it otherwise it would return 0 for ix==0.)
Incidentally, if you do want (int)log2() for a floating point number,
frexp() can be used to extract the exponent+1 (because the result is in
the range [0.5,1)). Or if you have a C99 library you can use logb() to
get the integer log2 value.
Chris C