用于计算c中设置的位数的程序

时间:2015-12-17 15:52:40

标签: c

我试图计算c中整数值中设置的位数。 但是对于某些值,它显示正确的位设置计数,而对于某些值则不显示。

PFB程序代码

int main()
{
    int a=512,i=0,j=1,count=0,k=0;

    for(i=0;i<31;i++)
    {
        if(k=a&j)
        {
            count++;
            j=j<<1;
        }
    }
    printf("the total bit set countis %d",count);
}

设置位值计数512的输出显示为零,如果使用的值为511,则显示为9。

请帮我纠正程序。

7 个答案:

答案 0 :(得分:3)

斯坦福大学有一页实现常见比特操作的不同方法。他们列出了5种不同的算法来计算所设置的位数,所有算法都用C示例。

https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive

他们最简单的实施:

unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v

for (c = 0; v; v >>= 1)
{
  c += v & 1;
}

答案 1 :(得分:2)

通常,您会计算无符号整数中的位数。例如,您通常要检查寄存器或掩码中设置的位。有符号整数用twos-compliment表示,我想不出你为什么要计算有符号整数中的设置位(如果你确实想要这个,那么会感兴趣)。

请注意,如果数字为负数,则右移或左移有符号整数是实现定义行为。来自C标准sectn 6.5.7:

  

...... E1的结果&lt;&lt; E2是E1左移E2位位置; ......如果是E1   具有有符号类型和非负值,并且E1 <&lt;&lt; E2是可表示的   在结果类型中,那就是结果值; 否则,   行为未定义。

     

E1&gt;的结果&gt; E2是E1右移E2   位位置。 ... 如果E1有签名类型和负值,则   结果值是实现定义的 ...

如果你想在任意大小的无符号整数中计算1,你可以使用this example

#include <stdio.h>

int main(void) {
   unsigned int value = 1234;
   unsigned int ones = 0;
   while(value > 0) {
      ones += value & 0x1;
      value >>= 1;
   }
   printf("#Ones = %u", ones);
}

使用这个例子value可以是unsigned char,unsigned long,无论无符号整数类型......

注意:不要移动有符号值或浮点/双打。

答案 2 :(得分:1)

您可以使用除法%和模int main() { int a = 512, count = 0; while(a != 0) { if(a % 2 == 1) { count++; } a /= 2; } printf("The total bit set is %d", count); } 运算符来检查以整数设置的位。

account is: {'Discover': ['username', 'dddddd']}

答案 3 :(得分:1)

你有几个错误:

for(i=0;i<32;i++) // <<< this should be 32, not 31
{
    if(k=a&j)
    {
        count++;
    }
    j=j<<1;       // <<< this needs to be outside the if block
}

请注意,对于int中的no位而不是使用32的硬编码值,最好这样做:

for(i=0;i<sizeof(int)*CHAR_BIT;i++)

这样,如果int的大小为例如,代码仍然有效。 16位或64位。

答案 4 :(得分:1)

如果您使用的是gcc / clang编译器,则可以使用内置函数 __ builtin_popcount

unsigned int user_input = 100
int count = __builtin_popcount(n); // count == 3

当我不寻找跨平台时,由于其高度优化,我将使用此功能。

答案 5 :(得分:0)

您正在检查a&j的值,如果a&j为0,那么除了重试之外别无其他。

你的j - bitshift需要在if-then之外。

答案 6 :(得分:0)

#include<stdio.h>
#include<conio.h>

int rem, binary = 0;
unsigned int

countSetBits (unsigned int n){

    unsigned int count = 0;

    while (n){
        count += n & 1;
        n >>= 1;
    }

    printf ("\n\t Number of  1's  in the binary number is : %d",count);
}

int dec_bin (int n){

    int i=1;

    while (n != 0){
        rem = n % 2;
        n = n / 2;
        binary = binary + (rem * i);
        i = i * 10;
    }

    printf("\n\t The converted Binary Equivalent is : %d",binary);
}

int main(){  
    int i = 0;

    printf ("\n\t Enter the Decimal Nummber: ");

    scanf ("%d", &i);

    int n= i;
    dec_bin(n);
    countSetBits (i);
    return 0;
}