找出特定整数有多少二进制数字

时间:2012-01-24 17:10:43

标签: c++ c algorithm

  

可能重复:
  Compute fast log base 2 ceiling

在C / C ++中将特定整数从十进制转换为二进制时,找出特定整数有多少二进制数字的最快方法是什么?

实施例。 47 (10) = 101111 (2)

所以47有六位数以二进制表示。

9 个答案:

答案 0 :(得分:10)

要快速有趣地执行此操作而无需调用数学函数,请检查以下内容:

for (digits = 0; val > 0; val >>= 1)
        digits++;

作为奖励,这应该煮至内存负载和2个正在使用的寄存器,以获得额外的惊人效果。

答案 1 :(得分:7)

如果您正在寻找最快的"就性能而言,您需要采用特定于平台的方法。

有些架构实际上有一个指令可以做到这一点。

在x86上,您有bsr指令。

在MSVC中,可以访问:

inline int bitlength(unsigned long x){
    if (x == 0)
        return 0;

    unsigned long index;
    _BitScanReverse(&index,x);
    return (int)(index + 1);
}

GCC __builtin_clz() intrinsic - 它做了类似的事情。

答案 2 :(得分:6)

my favorite collection of bit twiddling hacks提供的最快解决方案是Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup。它需要13条指令来查找数字中的最高设置位。

uint32_t v; // find the log base 2 of 32-bit v
int r;      // result goes here

static const int MultiplyDeBruijnBitPosition[32] = 
{
  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

v |= v >> 1; // first round down to one less than a power of 2 
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];

答案 3 :(得分:4)

传统方式

int count = 32;
for(int i = 1 << 31; i != 0; i >>= 1, count--)
    if((number & i) != 0) return count;

您可以通过优化获得更多的幻想。

EDIT 2 这是我在没有使用Bit Scan反向操作码的情况下能想到的最快的代码。您可以使用更大的(256条目)LUT并删除最后的IF语句。在我的测试中,这比在另一篇文章中描述的重复的OR-SHIFT然后LUT方法更快。

int[] Log2_LUT = new int[16]{0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
int Log2 (number) {
int count = 0;
if((number & 0xFFFF0000) != 0) { 
    number >>= 16;
    count += 16;
}
if((number & 0x0000FF00) != 0) { 
    number >>= 8;
    count += 8
}
if((number & 0x000000F0) != 0) {
    number >>= 4;
    count += 4;
}
return count + Log2_LUT[number];
}

或者,如果您的x86或x86-64位架构可以使用BSR(位扫描反向)操作码。 你可以找到它的c ++内在函数http://msdn.microsoft.com/en-us/library/fbxyd7zd%28v=vs.80%29.aspx

此外,您的问题与此问题类似What is the fastest way to calculate the number of bits needed to store a number

编辑为什么log2的答案不是最佳的...... 虽然在数学上是正确的,但复杂的浮点运算(正弦,余弦,tan,log)是现代计算机上执行速度最慢的操作。由于必须将整数转换为浮点数并且必须将其置于上限/下限,这一点更加复杂。

答案 4 :(得分:3)

尝试base-2对数:

ceil(log2(n))

答案 5 :(得分:2)

尝试使用对数:

ceil(log2(x))

答案 6 :(得分:2)

如果速度比可移植性更重要,那么一些编译器提供“计数前导零”功能。这可编译为某些处理器上的单个机器指令,包括现代x86和ARM。例如,使用GCC:

CHAR_BIT * sizeof x - __builtin_clz(x)

答案 7 :(得分:1)

如果整数至少为1,则所需的位为:

floor(log2(x)) + 1

答案 8 :(得分:0)

这是一种方式......

unsigned int count_bits(unsigned int n)
{
    unsigned int count = 0;

    if ( n <= 1 )
      return 1;

    do
      count++;
    while( n >>= 1 );

    return count;
}