法一:参数num%2若为1表示第一位补码是1,反则不是,num/2是将参数num向右移动一位,继续判断第一位补码是否为1,依次循环到num为0。最后统计补码有多少个1。
10的二进制补码:1010 10%2=0
10/2=5的二进制补码:0101 5%2=1
5/2=2的二进制补码:0010 2%2=0
2/2=1的二进制补码:0001 1%2=1
#include <stdio.h>
int NumberOf1(unsigned int num) {//计算参数num的二进制补码中有几个1
int count = 0;//统计1的个数
while (num) {
if (1 == num % 2) {
count++;
}
num /= 2;
}
return count;
}
int main() {
int n = 10;
int ret= NumberOf1(n);
printf("%d的二进制补码中有 %d 个1\n",n, ret);
return 0;
}
运行结果:

法二:用参数num的每一位和1按位与,若为1表示当前位为1,反则是0。
10的二进制补码:1010 1的二进制补码:0001
1010&0001=0
向右移一位:0101
0101&0001=1
再向右移一位:0010
0010&0001=0
再向右移一位:0001
0001&0001=1
再向右移一位:0000
0000&0001=0
#include <stdio.h>
int NumberOf2(int num) {
int count = 0;
int i = 0;
for (i = 0; i < 32; i++) {
if (((num >> i) & 1) == 1) {
count++;
}
}
return count;
}
int main() {
int n = 10;
int ret= NumberOf2(n);
printf("%d的二进制补码中有 %d 个1\n",n, ret);
return 0;
}
运行结果:

法三:
num=num&(num-1)
num=15
1111 —— num
1110 —— num-1
1110 —— num
1101 —— num-1
1100 —— num
... 0000 —— num 每次去掉二进制位最右边的1
#include <stdio.h>
int NumberOf3(int num) {
int count = 0;
while (num ) {
num = num & (num - 1);
count++;
}
return count;
}
int main() {
int n = 10;
int ret= NumberOf3(n);
printf("%d的二进制补码中有 %d 个1\n",n, ret);
return 0;
}
运行结果:
