在求对二的补码时,表达式x&=(x -1)可以删除x中最右边值为1的一个二进制位。请解释这样做的道量。用这一方法重写bitcount函数,以加快其执行速度。
对一个8位的数,x-1的结果有两种可能:
xxxx-xxx1 => x
xxxx-xxx0 => x - 1
xxxx-xxx0 => x&(x-1)
显然是删除了最右边的1
xxx1-0000 => x
xxx0-1111 => x - 1
xxx0-0000 => x&(x-1)
也是成立的。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GetBin(char *p, int num);
void GetChoiceBin(unsigned int num, int choice);
int bitcount(unsigned x);
int main(void)
{
unsigned x = 0;
scanf("%d", &x);
GetBin("char", x);
printf("%d\n", bitcount(x));
return 0;
}
int bitcount(unsigned x)
{
if (x == 0)
return 0;
int count = 1;
while (x &= (x - 1))
{
count++;
}
return count;
}
void GetBin(char *p, int num)
{
char *array[] = {
"char",
"int",
};
int choiceLength = sizeof(array) / sizeof(array[0]);
for (int i = 0; i < choiceLength; i++)
{
if (!strncmp(p, array[i], 4))
{
GetChoiceBin(num, i);
return ;
}
}
printf("No find!\n");
}
void GetChoiceBin(unsigned int num, int choice)
{
unsigned int length = 0;
if (choice == 0)
{
if (num > 255)
{
printf("The char can`t big 255!\n");
exit(EXIT_FAILURE);
}
length = sizeof(char) * 8;
}
if (choice == 1)
length = sizeof(int) * 8;
unsigned int array[length];
int i = 0;
int count = 1;
for (i = 0; num != 0; i++)
{
array[i] = num % 2;
num /= 2;
}
for (int j = 0; j < length - i; j++, count++)
{
printf("0");
if (count % 4 == 0)
{
printf("-");
}
}
for (--i; i >= 0; i--, count++)
{
printf("%d", array[i]);
if (count % 4 == 0 && count != length)
{
printf("-");
}
}
printf("\n");
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210415193232400.png)