计算二进制中1的个数
众所周知,
二进制是由1和0组成。 十进制是由0到9的是个数字组成。
计算十进制的某个数的个数,相比大家一眼就能看出,
但如何用计算机逻辑去计算呢?
接下来就和大家一起来探讨
给定一个十进制数 1234
通过%10得到最后一位,然后/10将最后一位去掉。 反复操作,直到/10的结果为0。 经过此操作便可获得十进制中的每个数
由此是不是可以联想到,获得二进制的每个数也是如此呢?
答案当然是如此
下面就用代码进行实现
#include<stdio.h> int main() { int i = 0; int count = 0;//用于统计1的个数 scanf("%d", &i); while (i) { if (i % 2 == 1) { count++; } i /= 2; } printf("%d\n", count); return 0; }
-1的二进制为 11111111111111111111111111111111 当输入的数值为负数,此方法就失效啦
会不会有别的方法可以更加准确地计算二进制中1的个数?
因为操作符中的按位与,按位或和按位异或可对二进制位进行操作,所有这些操作符是不是可以用来计算二进制中一个个数呢?
按位与操作符,在二进制中相同位置,两数相同为1,否则为0
由此可以想到,如果1去按位与这个数;
如果,这个数二进制中最后一位是1,则结果为1 否则,结果为零。
然后再通过右移操作符每次移动一位,就可计算这个数的二进制中1的个数
代码实现如下
#include<stdio.h> int main() { int num = 0; scanf("%d", &num); int count = 0;//用于统计二进制中1的个数 int i = 0; for (i = 0; i < 32; i++) { if ((num >> i) & 1 == 1) { count++; } } printf("%d\n", count); return 0; }
就算输入的是负值,结果也是正确的,所以此方法是正确的
到这里会发现一个问题,此方法虽然正确,但是太过繁琐。
就算是数字0也要循环32次
因此应该想着如何去完善这个代码
通过上面的操作,先确定一个数n,然后计算n-1; 再将两者按位与n&(n-1), 然后将其赋值给n,n=n&(n-1); 重复操作,直到n=0。**循环的次数**便是二进制中1的个数。
代码如下
#include<stdio.h> int main() { int num = 0; scanf("%d", &num); int count = 0;//用于统计二进制1的个数 while (num) { num = num & (num - 1); count++; } printf("%d\n", count); return 0; }