除了log_2(x)
之外还有什么方法可以确定整数是多少?当然知道它是2的幂,(二进制基0001
,0010
,0100
,1000
等...)。
大多数情况下,我不希望它转换为浮点数,我不希望它简单地使用数组搜索。
答案 0 :(得分:2)
你想要做的是计算一个数字的尾随零,虽然计算前导零并从32或64减去也可以正常工作是两个人的力量。 Bit Twiddling Hacks提供了很多方法来实现这一目标。
右侧线性计算连续零位(尾随)
unsigned int v; // input to count trailing zero bits
int c; // output: c will count v's trailing zero bits,
// so if v is 1101000 (base 2), then c will be 3
if (v)
{
v = (v ^ (v - 1)) >> 1; // Set v's trailing 0s to 1s and zero rest
for (c = 0; v; c++)
{
v >>= 1;
}
}
else
{
c = CHAR_BIT * sizeof(v);
}
并行计算右侧的连续零位(尾随)
unsigned int v; // 32-bit word input to count zero bits on right
unsigned int c = 32; // c will be the number of zero bits on the right
v &= -signed(v);
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c -= 1;
通过二进制搜索计算右侧的连续零位(尾随)
unsigned int v; // 32-bit word input to count zero bits on right
unsigned int c; // c will be the number of zero bits on the right,
// so if v is 1101000 (base 2), then c will be 3
// NOTE: if 0 == v, then c = 31.
if (v & 0x1)
{
// special case for odd v (assumed to happen half of the time)
c = 0;
}
else
{
c = 1;
if ((v & 0xffff) == 0)
{
v >>= 16;
c += 16;
}
if ((v & 0xff) == 0)
{
v >>= 8;
c += 8;
}
if ((v & 0xf) == 0)
{
v >>= 4;
c += 4;
}
if ((v & 0x3) == 0)
{
v >>= 2;
c += 2;
}
c -= v & 0x1;
}
还有三个使用浮点数和数组查找的例子,你已经指定了它们不想使用它们。
答案 1 :(得分:1)
有几种方法可以做到。一个在我的头顶,你可以将它除以2,直到它是1
:
int logbase2( unsigned int n ) {
int exp = 0;
if ( n == 0 )
return -1;
while ( n != 1 ) {
n /= 2;
exp++;
}
return exp;
}
而logbase2( yournumber );
将产生你想要的结果。更一般地说,它应该在数字yournumber
的基数2上产生实际对数的整数部分。
答案 2 :(得分:0)
您可以使用基于迭代操作的位比较测试:
unsigned int power_of_2(unsigned int x) {
// Note that *8 hardcoded isn't ideal here. There's a constant available that
// specifies the 'byte' size (bitwise) for the actual architecture.
// But this is really depending on your C or C++ compiler.
for(size_t p2 = 0; p2 < sizeof(x)*8; ++p2) {
if(x & (1 << p2)) {
return p2;
}
}
return 0;
}
以下调用为您提供如下所示的输出:
int main() {
std::cout << power_of_2(0x0080) << " "
<< power_of_2(0x0040) << " "
<< power_of_2(0x0020) << " "
<< power_of_2(0x0010) << " "
<< std::endl;
return 0;
}
输出:
7 6 5 4
请检查实时样本here。