GCC __builtin_clz转换为x86/x64上的BSR,ARM上的CLZ等,如果硬件没有实现,则模拟指令.
Visual C++ 2005及以上版本_BitScanReverse.
使用这些功能,你可以得到你的k
维基百科使用按位运算符编写如何执行此操作:
/**
* Returns the floor form of binary logarithm for a 32 bit integer.
* ?1 is returned if ''n'' is 0.
*/
int floorLog2(unsigned int n) {
if (n == 0)
return -1;
int pos = 0;
if (n >= 1<<16) { n >>= 16; pos += 16; }
if (n >= 1<< 8) { n >>= 8; pos += 8; }
if (n >= 1<< 4) { n >>= 4; pos += 4; }
if (n >= 1<< 2) { n >>= 2; pos += 2; }
if (n >= 1<< 1) { pos += 1; }
return pos;
}
Run Code Online (Sandbox Code Playgroud)
代码取自:维基百科:二进制对数此页面已被修改,原始版本的代码示例仍然可以找到她:维基百科:二进制对数(2011年5月24日)
好吧,您可以利用二进制指数显式存储在浮点数中的事实:
unsigned log2(unsigned x)
{
float f = x;
memcpy(&x, &f, sizeof x);
return (x >> 23) - 127;
}
Run Code Online (Sandbox Code Playgroud)
我不知道这有多快,而且它肯定不是最便携的解决方案,但我发现它很有趣。
只是为了好玩,这里有一个完全不同的、相对简单的解决方案:
unsigned log2(unsigned x)
{
unsigned exp = 0;
for (; ;)
{
switch (x)
{
case 128: ++exp;
case 64: ++exp;
case 32: ++exp;
case 16: ++exp;
case 8: ++exp;
case 4: ++exp;
case 2: ++exp;
case 1: return exp;
case 0: throw "illegal input detected";
}
x >>= 8;
exp += 8;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个完全展开的解决方案:
#define CASE(exp) case (1 << (exp)) : return (exp);
unsigned log2(unsigned x)
{
switch (x)
{
CASE(31) CASE(30) CASE(29) CASE(28)
CASE(27) CASE(26) CASE(25) CASE(24)
CASE(23) CASE(22) CASE(21) CASE(20)
CASE(19) CASE(18) CASE(17) CASE(16)
CASE(15) CASE(14) CASE(13) CASE(12)
CASE(11) CASE(10) CASE( 9) CASE( 8)
CASE( 7) CASE( 6) CASE( 5) CASE( 4)
CASE( 3) CASE( 2) CASE( 1) CASE( 0)
default: throw "illegal input";
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1212 次 |
| 最近记录: |