简体   繁体   English

C 中的位计数类似于 bit twiddling hack

[英]Bit Counting in C similar to bit twiddling hack

I need to make a routine that counts bits in a word that does not involve loops (only bit operations), and does not use large constants.我需要制作一个例程来计算不涉及循环(仅位操作)并且不使用大常量的字中的位。

int x = 0xFFFFFFFF;
x += (~((x >> 1) & 0x55555555)+1);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0F0F0F0F);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003F);

This I found on bit twiddling hacks, but the largest constant I can use is 0xFF... Not sure how to do this otherwise.这是我在 bit twiddling hacks 上发现的,但我可以使用的最大常量是 0xFF ... 不知道该怎么做。

Thanks folks.谢谢大家。

You can for example use a constant array COUNTS[16] which is the number of set bits in the binary representation of numbers from 0 to 15. Then:例如,您可以使用常量数组COUNTS[16] ,它是从 0 到 15 的数字的二进制表示中设置的位数。然后:

static inline int byte_count (int x) {
  static const int COUNTS[16] = { 0, 1, 1, 2, 1, /* fill in the rest manually */ };
  return COUNTS[x & 15] + COUNTS[x >> 4];
}

int count(int x) {
  return byte_count(x >> 24) + byte_count((x >> 16) & 255) + byte_count((x >> 8) & 255) + byte_count(x & 255);
}

No loops and no constants larger than 255.没有循环,也没有大于 255 的常量。

Using your algorithm:使用你的算法:

int x = 0xFF;
x |= (x << 8);  // x = 0xFFFF
x |= (x << 16); // x = 0xFFFFFFFF

and then the rest of the code - provided it works.然后是代码的 rest - 如果它有效。

Recursive solution:递归解决方案:

int foo ( int x )
{
    if ( x == 0 )
        return 0;
    return (x & 1) + foo ( x/2 );
}

your question is already answered here你的问题已经在这里得到解答

int NumberOfSetBits(int i)
{
    i = i - ((i >> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM