这是计算二进制数中0的数量的正确方法吗?

时间:2015-01-07 01:59:30

标签: c binary bit

#include <stdio.h>

int NumberOfSetBits(int);

int main(int argc, char *argv[]) {
    int size_of_int = sizeof(int);
    int total_bit_size = size_of_int * 8;

    // binary representation of 3 is 0000011 
    // C standard doesn't support binary representation directly
    int n = 3; 
    int count = NumberOfSetBits(n);
    printf("Number of set bits is: %d\n", count);
    printf("Number of unset bits is: %d", total_bit_size - count);
}

int NumberOfSetBits(int x)
{
    int count = 0;
    //printf("x is: %d\n", x);
    while (x != 0) {
        //printf("%d\n", x);
        count += (x & 1);
        x = x >> 1;
    }
    return count;
}
  

设置位数为:2

     

未设置位数是:30

int size_of_int = sizeof(int);
int total_bit_size = size_of_int * 8;

^将获得系统上int的大小并将其乘以8,这是每个字节中的位数

编辑:不使用〜

/*
    Calculate how many set bits and unset bits are in a binary number aka how many 1s and 0s in a binary number
*/
#include <stdio.h>

unsigned int NumberOfSetBits(unsigned int);
unsigned int NumberOfUnSetBits(unsigned int x);


int main() {

    // binary representation of 3 is 0000011 
    // C standard doesn't support binary representation directly    
    unsigned int n = 3; 
    printf("Number of set bits is: %u\n", NumberOfSetBits(n));
    printf("Number of unset bits is: %u", NumberOfUnSetBits(n));

    return 0;
}

unsigned int NumberOfSetBits(unsigned int x) {
    // counts the number of 1s
    unsigned int count = 0;

    while (x != 0) {
        count += (x & 1);
        // moves to the next bit
        x = x >> 1;
    }
    return count;
}

unsigned int NumberOfUnSetBits(unsigned int x) {

    // counts the number of 0s
    unsigned int count = 0; 
    while(x != 0) {
        if ((x & 1) == 0) {
            count++;
        }
        // moves to the next bit
        x = x >> 1; 
    }
    return count;
}

返回输入3

Number of set bits is: 2
Number of unset bits is: 0

未设置位为0?看起来不对吗?

如果我使用NumberOfSetBits(~n)则返回30

3 个答案:

答案 0 :(得分:1)

你在某些系统上遇到了问题,因为你在位计数函数中右移一个有符号整数,这可能会在每次负整数时将1移入MSB。 请改用unsigned int(或仅unsigned):

int NumberOfSetBits(unsigned x)
{
    int count = 0;
    //printf("x is: %d\n", x);
    while (x != 0) {
        //printf("%d\n", x);
        count += (x & 1);
        x >>= 1;
    }
    return count;
}

如果您解决了问题的这一部分,可以使用以下方法解决另一个问题:

int nbits = NumberOfSetBits(~n);

其中~按位反转n中的值,因此'设置位计数'计算为零的位。

还有更快的算法来计算设置的位数:请参阅Bit Twiddling Hacks

答案 1 :(得分:1)

这是计算二进制数

中零的数量的正确方法
#include <stdio.h>

unsigned int binaryCount(unsigned int x)
{
    unsigned int nb=0; // will count the number of zeores 
    if(x==0) //for the case zero we need to return 1
        return 1;
    while(x!=0)
    {
        if ((x & 1) == 0) // the condition for getting the most right bit in the number
        {
            nb++;
        }
        x=x>>1; // move to the next bit 
    }
    return nb;
}

int main(int argc, char *argv[])
{
    int x;
    printf("input the number x:");
    scanf("%d",&x);
    printf("the number of 0 in the binary number of %d is %u \n",x,binaryCount(x));

    return 0;
}

答案 2 :(得分:0)

解决NumberOfSetBits(int x)版本而不假设2的补码也不存在填充比特是一个挑战。

@Jonathan Leffler有正确的方法:使用unsigned。 - 只是想我会尝试一个通用的int

x > 0,OP的代码正常

int NumberOfSetBits_Positive(int x) {
  int count = 0;
  while (x != 0) {
    count += (x & 1);
    x = x >> 1;
  }
  return count;
}

使用以下命令查找位宽而不计算填充位。

BitWidth = NumberOfSetBits_Positive(INT_MAX)  + 1;

这样,0或1位的计数是微不足道的。

int NumberOfClearBits(int x) {
  return NumberOfSetBits_Positive(INT_MAX)  + 1 - NumberOfSetBits(x);
}

int NumberOfSetBits_Negative(int x) {
  return NumberOfSetBits_Positive(INT_MAX)  + 1 - NumberOfSetBits_Positive(~x);
}

剩下的就是找到x为0时设置的位数。+ 0很容易,答案是0,但是-0(1的恭维或符号幅度)是BitWidth或1。

int NumberOfSetBits(int x) {
  if (x > 0) return NumberOfSetBits_Positive(x);
  if (x < 0) return NumberOfSetBits_Negative(x);

  // Code's assumption: Only 1 or 2 forms of 0.  
  /// There may be more because of padding.
  int zero = 0;
  // is x has same bit pattern as +0
  if (memcmp(&x, &zero, sizeof x) == 0) return 0;
  // Assume -0
  return NumberOfSetBits_Positive(INT_MAX)  + 1 - NumberOfSetBits_Positive(~x);
}