C 计算无符号整数中位转换数的最快方法

C 计算无符号整数中位转换数的最快方法,c,bit,counting,C,Bit,Counting,我正在寻找计算无符号int中位转换数的最快方法 如果int包含:0b0000000000000000000001010 转换的数量为:4 如果int包含:0b0000000000000000000001001 转换的数量为:3 语言是C。什么语言 我将循环64次,然后对你的数字进行位移位,以检查位的大小,然后存储上一位并将其与当前位进行比较。如果不同,则增加计数。好的,对于转换,您的意思是,如果您遍历0-s和1-s字符串,则计算0跟在1后面或1跟在0后面的每种情况 通过将位移出并计算更改,这很容

我正在寻找计算
无符号int
中位转换数的最快方法

如果int包含:
0b0000000000000000000001010

转换的数量为:4

如果int包含:
0b0000000000000000000001001

转换的数量为:3

语言是C。什么语言


我将循环64次,然后对你的数字进行位移位,以检查位的大小,然后存储上一位并将其与当前位进行比较。如果不同,则增加计数。

好的,对于转换,您的意思是,如果您遍历0-s和1-s字符串,则计算0跟在1后面或1跟在0后面的每种情况

通过将位移出并计算更改,这很容易:

transitions(n)
  result = 0
  prev = n mod 2
  n = n div 2
  while n<>0 
    if n mod 2 <> prev then
      result++
      prev = n mod 2
    fi
    n = n div 2
  elihw
  return result
转换(n)
结果=0
上一个=n模式2
n=n第2部分
而n0
如果n mod 2 prev,则
结果++
上一个=n模式2
fi
n=n第2部分
以利赫
返回结果

您可以用班次替换mod和div。

最快取决于您的场景: 当您将数据类型指定为常量大小(unsigned int)时,可以使用查找表。但是当您只需要执行一次此操作时,初始化表的恒定开销太大,尽管如此,通过int进行扫描+计数的速度要快得多

我想最好的组合是:在表中查找一个字节或字(256或64k条目并不多),然后按最后/第一位组合字节/字

int numTransitions(int a)
{
  int b = a >> 1; // sign-extending shift properly counts bits at the ends
  int c = a ^ b;  // xor marks bits that are not the same as their neighbors on the left
  return CountBits(c); // count number of set bits in c
}

要在C/C++中高效实现see

,我将执行以下操作:

unsigned int Transitions(unsigned int value)
{
    unsigned int result = 0;

    for (unsigned int markers = value ^ (value >> 1); markers; markers = markers >> 1)
    {
        if (markers & 0x01) result++;
    }

    return result;
}

下面是使用算术移位+xor和Kernighan位计数方法的代码:

int count_transitions(int x)
{
    assert((-1 >> 1) < 0); // check for arithmetic shift
    int count = 0;
    for(x ^= (x >> 1); x; x &= x - 1)
        ++count;
    return count;
}
int count\u转换(int x)
{
断言(-1>>1)<0);//检查算术移位
整数计数=0;
对于(x^=(x>>1);x;x&=x-1)
++计数;
返回计数;
}

256字节的查找表非常合理,但64k的查找表肯定会破坏一级缓存。我认为您的实现中有一个错误:如果我给它:0x8000000b=0B1000000000000000000000011,它有4个状态,那么您的函数计数为5!这仅仅是因为迭代不限于32位(以减少操作数),我想您可以添加一个额外的检查,但这将添加操作,这将使其速度减慢一点。这个实现基本上是Crashworks解决方案的紧凑版本。使用shift+xor也是我的第一个想法。