The question is
Are there any other (and/or faster) implementations of a basic 2log?
Applications
The log2(int) and
There have been quite a few answers providing fast approximate approaches to log2(int) but few for log2(float), so here's two (Java implementation given) that use both a lookup table and mantissa/bit hacking:
/**
* Calculate the logarithm to base 2, handling special cases.
*/
public static float log2(float x) {
final int bits = Float.floatToRawIntBits(x);
final int e = (bits >> 23) & 0xff;
final int m = (bits & 0x7fffff);
if (e == 255) {
if (m != 0) {
return Float.NaN;
}
return ((bits >> 31) != 0) ? Float.NaN : Float.POSITIVE_INFINITY;
}
if ((bits >> 31) != 0) {
return (e == 0 && m == 0) ? Float.NEGATIVE_INFINITY : Float.NaN;
}
return (e == 0 ? data[m >>> qm1] : e + data[((m | 0x00800000) >>> q)]);
}
Note:
/**
* Calculate the logarithm using base 2. Requires the argument be finite and
* positive.
*/
public static float fastLog2(float x) {
final int bits = Float.floatToRawIntBits(x);
final int e = (bits >> 23) & 0xff;
final int m = (bits & 0x7fffff);
return (e == 0 ? data[m >>> qm1] : e + data[((m | 0x00800000) >>> q)]);
}
This second method forgoes the checking present in the other method and therefore has the following special cases:
Both methods upon rely on a lookup table data (and variables q and qm1). These are populated with the following method. n defines the accuracy-space tradeoff.
static int q, qm1;
static float[] data;
/**
* Compute lookup table for a given base table size.
*
* @param n The number of bits to keep from the mantissa. Table storage =
* 2^(n+1) * 4 bytes, e.g. 64Kb for n=13. Must be in the range
* 0<=n<=23
*/
public static void populateLUT(int n) {
final int size = 1 << (n + 1);
q = 23 - n;
qm1 = q - 1;
data = new float[size];
for (int i = 0; i < size; i++) {
data[i] = (float) (Math.log(i << q) / Math.log(2)) - 150;
}
}
populateLUT(12);
log2(6666); // = 12.702606