I need a Very-Fast implementation of log2(float x) function in C++.
I found a very interesting implementation (and extremely fast!)
#include <intrin.h>
inline unsigned long log2(int x)
{
unsigned long y;
_BitScanReverse(&y, x);
return y;
}
But this function is good only for integer values in input.
Question: Is there any way to convert this function to double type input variable?
UPD:
I found this implementation:
typedef unsigned long uint32;
typedef long int32;
static inline int32 ilog2(float x)
{
uint32 ix = (uint32&)x;
uint32 exp = (ix >> 23) & 0xFF;
int32 log2 = int32(exp) - 127;
return log2;
}
which is much faster than the previous example, but the output is unsigned type.
Is it possible to make this function return a double type?
Thanks in advance!
If you just need the integer part of the logarithm, then you can extract that directly from the floating point number.
Portably:
#include <cmath>
int log2_fast(double d) {
int result;
std::frexp(d, &result);
return result-1;
}
Possibly faster, but relying on unspecified and undefined behaviour:
int log2_evil(double d) {
return ((reinterpret_cast<unsigned long long&>(d) >> 52) & 0x7ff) - 1023;
}
MSVC + GCC compatible version that give XX.XXXXXXX +-0.0054545
float mFast_Log2(float val) {
union { float val; int32_t x; } u = { val };
register float log_2 = (float)(((u.x >> 23) & 255) - 128);
u.x &= ~(255 << 23);
u.x += 127 << 23;
log_2 += ((-0.3358287811f) * u.val + 2.0f) * u.val -0.65871759316667f;
return (log_2);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With