目录
方法一:累除法
- #include<stdio.h>
- //方法1:累除法
- int count_num(unsigned int n)
- {
- int count = 0;
- while (n)
- {
- if (n % 2 == 1)
- count++;
- n /= 2;
- }
- return count;
- }
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- //n=5 000101
- int ret = count_num(n);
- printf("%d\n", ret);
- return 0;
- }
这里注意:值传递的时候要把n设为unsigned int 即无符号整形
原因,不设置只能求正数的位数,正数原反补相同,所以可以正常使用
而负数是以补码的形式存储在内存中且最高位为符号位,不参与运算,设置为unsigned int最高位便可以参与运算,而非符号位了。
方法二:位操作法
-
- #include<stdio.h>
- int count_num(int n)
- {
- int count = 0;
- int a = 32;
- while (i--)
- {
- if ((n & 1) == 1)
- count++;
- n >>= 1;
- }
- return count;
-
- }
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- n=5 000101
- int ret = count_num(n);
- printf("%d\n", ret);
- return 0;
- }
-
-
根据以前的笔记,n的二进制补码向右移动一位,有算数右移和逻辑右移,为保险起见,循环次数为32位,防止因为不同编译器右移方式不同而出错。
方法三:位操作法2.0
这里出示一个nb的做法
n&(n-1)这个表达式可以将n的二进制补码的最后一位剥离出来,十分美妙。
举例子
00000000000000000000000000000101 5 的补码
00000000000000000000000000000100 (5-1)的补码
按位与& 可得
00000000000000000000000000000100 剥离出了最低位的1
循环可知最后结果
- #include<stdio.h>
-
- int count_num(int n)
- {
- int count = 0;
- while (n)
- {
- count++;
- n = n & (n - 1);
- }
- return count;
- }
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- int ret = count_num(n);
- printf("%d\n", ret);
- return 0;
- }
注意:应该先计数,再使用完美的公式。