/*
输入一个整数,求这个整数存储在内存中的二进制中1的个数
*/
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//方法一
int Num1(int n)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++) //让n的二进制的每一位和1按位与
{
if (n & (1 << i)) //也可以if ((n >> i) & 1) 若检测有多少个0,改为:if (!(n & (1 << i)))
{
count++;
}
}
return count;
}
//方法二
int Num2(int n)
{
/*
数 % 进制数 = 该数最右边一位 | 数 / 进制数 = 除去该数最右边一位
10进制:123
123 % 10 = 3 123 / 10 = 12
12 % 10 = 2 12 / 10 = 1
1 % 10 = 1 1 / 10 = 0
2进制:00000000 00000000 00000000 00001111 (15)
15 % 2 = 1 15 / 2 = 7 -- 00000111
7 % 2 = 1 7 / 2 = 3 -- 00000011
3 & 2 = 1 3 / 2 = 1 -- 00000001
1 % 2 = 1 1 / 2 = 0 -- 00000000
*/
size_t m = (size_t)n; //若n是负数则要强制转换成无符号数,例如-1会变成一个很大的数:11111111 11111111 11111111 11111111
int count = 0;
do
{
if (m % 2 == 1)
{
count++;
}
} while (m = m / 2);
return count;
}
//方法三
int Num3(int n)
{
/*
n = n & (n - 1) 每执行一次,n的二进制右边少一个1
15: 00001111 & 00001110 = 00001110
00001110 & 00001101 = 00001100
00001100 & 00001011 = 00001000
00001000 & 00000111 = 00000000
*/
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
int n = 0, i = 0, count = 0;
scanf("%d", &n);
printf("%d\n", Num1(n));
printf("%d\n", Num2(n));
printf("%d\n", Num3(n));
return 0;
}