1.计算一个数字二进制补码里面1的个数
(1)方法一
根据这个10进制的整数,对这个数进行%10,/10不断地进行下去,
%10得到最后一位,/10得到舍去最后一位之后剩余的数;
同理得到:二进制就进行%2/2的操作,不断地进行下去,
%2==1就计数,否则就/2,知道结果是0就退出循环;
int countone(unsigned int m)
{
	int count = 0;
	while (m)
	{
		if (m % 2 == 1)
		{
			count++;
		}
		m = m / 2;
	}
	return count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = countone(n);
	printf("%d\n", ret);
	return 0;
}这个里面传参类型设置成unsigned int是因为-1这个特例

但是如果直接输入-1,-1%2不是1,-1/2=0就会直接跳出循环,无法正常计数,所以转换成为无符号整形;
(2)方法二
int countone(int m)
{
	int count = 0;
	int i = 0;
	for(i=0;i<32;i++)
	{
		if ((m>>i) & 1  == 1)
		{
			count++;
		}
	}
	return count;
}这里的m右移i位和1进行按位与运算,32个比特位构成一个循环,依次进行判断输出最后的个数;
(3)方法三

通过这个我们发现m&(m-1)每次都能去掉二进制序列里面后面的一个数字1,这样就可以有几个1就进行几次循环,大大的提高了效率,相比于第二种方法很快,因为第二种无论是否为0都要进行判断,而这种只需要判断是0的数位,但是这种方法难以想到;
int countone(int m)
{
	int count = 0;
	while (m)
	{
		count++;
		m = m & (m - 1);
	}
	return count;
}这里要先进行加加操作,然后每一次就减少一个0;
2.把一个数字的二进制位的某一位0变成1再变成0
#include <stdio.h>
int main()
{
 int a = 13;
 a = a | (1<<4);
 printf("a = %d\n", a);
 a = a & ~(1<<4);
 printf("a = %d\n", a);
 return 0;
}比如10:00000000 00000000 00000000 00001010把第5位变成0再恢复1
(1)变成0就是把把1左移4位,进行按位或操作,0变为1,后面的和0或操作,1还是1,0还是0,无影响;
(2)再变成0就是做以后取反和a进行按位与操作,原为数字1就变为0其他的和1进行,1还是1,0还是0
换成其他的数字,该方法也是用,只是需要左移n-1位,n是题目要求的第几位数字,这个例子第五
位进行变化,就左移4位
3.输入2个数字,判断他们的二进制位不同的位数
(1)先进行按位异或,相同就是0,不同就是1;
(2)统计1的个数,就回到了第一题的方法;
#include <stdio.h>
int main(){
    int a=0;
    int b=0;
    int c=0;
    int count=0;
    while(scanf("%d %d",&a,&b)!=EOF)
    {
        c=a^b;
        while(c)
        {
            c=c&(c-1);
            count++;
        }
    }
    printf("%d",count);
    return 0;
}4.分别打印一个数字的二进制序列的奇数位和偶数位数字
void Printbit(int num)
{
	for (int i = 31; i >= 1; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");
	for (int i = 30; i >= 0; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");
}
int main()
{
	int m = 0;
	scanf("%d", &m);
	Printbit(m);
	return 0;
}这个主要难在如何打印:
(1)是1就打印1,是0就打印0;
(2)将这个二进制序列右移并和1进行按位与运算
例如:第一位是奇数位,向右移动31位,和1进行按位与运算,是1就打印1,是0就打印0;



















