【C语言】求二进制中1的个数(三种方法)

前言
🎈大家好,我是何小侠🎈
🌀大家可以叫我**小何或者小侠🌀**
🔴我是一名普通的博客写作者🔴
💐希望能通过写博客加深自己对于学习内容的理解💐
🌸也能帮助更多人理解和学习🌸
🍃我的主页: 何小侠的主页🍃

在这里插入图片描述


    这篇博客我们一起来学习有关于二进制位的操作。希望能提高大家对二进制的理解。
    🍊

    在这里插入图片描述

    题目🍊

    编写代码实现:求一个整数存储在内存中的二进制中1的个数。
    我们下面介绍三种方法

    第一种方法🍊

    在介绍第一种方法之前我们先要知道一个概念,会有利于我们理解。

    假如有n = 1234 这样一个数据,如果我们 %10 就得到了4 ,
    如果我们 /10 就得到123,这个大家应该是理解的,但是换在二进制又如何呢?

    在这里插入图片描述

    int main()
    {
    	int i = 0;
    	scanf("%d", &i);
    	int count = 0;
    	while (i != 0)
    	{
    		if (i % 2 == 1)
    		count++;
    		i /= 2;
    
    	}
    	printf("%d", count);
    
    	return 0;
    }
    

    这就是我们具体的代码,我们看看运行情况
    在这里插入图片描述
    但是无法在i 为负数的情况下使用。
    在这里插入图片描述

    while (i != 0)
    	{
    		if (i % 2 == 1)
    		count++;
    		i /= 2;
    
    	}
    

    如果 i 为-1,那么 i %2 == -1 ,-1/=2后,i就变成了0,然后while就进不去了,
    所以解决办法是什么呢?
    我们将i的类型转换为unsigned int 就行了,永远从无符号的角度去看就行。

    int main()
    {
    	unsigned int i = 0;
    	scanf("%d", &i);
    	int count = 0;
    	while (i != 0)
    	{
    		if (i % 2 == 1)
    		count++;
    		i /= 2;
    
    	}
    	printf("%d", count);
    
    	return 0;
    }
    

    在这里插入图片描述

    第二种方法🍊

    第二种是最常见的方法,也是比较好想的方法,应该要掌握好

    我们知道1的二进制位是
    00000000000000000000000000000001
    如果1&上任何一个数就能知道这个数的第一位是多少
    比如
    -1的补码与上1
    1111 1111 1111 1111 1111 1111 1111 1111
    00000000000000000000000000000001
    结果就是00000000000000000000000000000001 (&后的结果)
    如果说我们能让1左移1位就能得到二进制的第二位是多少,
    1111 1111 1111 1111 1111 1111 1111 1111
    00000000000000000000000000000010
    00000000000000000000000000000010
    那么通过不断的左移,如果左移后&的结果不为0就说明有一个1,

    int main()
    {
    	unsigned int i = 0;
    	scanf("%d", &i);
    	int count = 0;
    	int n = 0;
    	for(n = 0; n < 32; n++)
    	{
    		if ((i & (1 << n))!= 0)
    		{
    			count++;
    		}
    	}
    	printf("%d", count);
    
    	return 0;
    }
    

    注意这里if 最好不要像这样写,首先!=的优先级是高于&的所以要加(),那也就是说我们直接写成if(i&(1 << n))就行了。这个是第一点。
    然后其实我们也可以直接移动i的二进制位,不断的右移

    int main()
    {
    	unsigned int i = 0;
    	scanf("%d", &i);
    	int count = 0;
    	int n = 0;
    	for(n = 0; n < 32; n++)
    	{
    		if ((i>>n) & 1)
    		{
    			count++;
    		}
    	}
    	printf("%d", count);
    
    	return 0;
    }
    

    我个人还是比较推荐移动所求数的二进制位,因为得出来的结果只可能是1或0;

    第三种方法🍊

    该方法也是与其他两种方法拉开水平的一种,如果你想让别人感觉你对二进制位理解的很到位,你就可以写这种方法。
    我们现在来讲解
    在这里插入图片描述
    最后的代码也比较简单

    int main()
    {
    	unsigned int i = 0;
    	scanf("%d", &i);
    	int count = 0;
    	int n = 0;
    	while (i)
    	{
    		i = i & (i - 1);
    		count++;
    	   }
    	printf("%d", count);
    
    	return 0;
    }
    

    在这里插入图片描述

    再来一题🍊

    写一个代码判断一个数是不是2的n次幂
    我们简单说一下
    因为2的二次幂的二进制中只有一个1,所以,只二进制中只有1个1的时候才能说明是2的2次幂

    int main()
    {
    	unsigned int i = 0;
    	scanf("%d", &i);
    	//8
    	//00001000
    	//00000111 7
    	//00000000
    	if ((i & (i - 1)) == 0)
    	{
    		printf("是");
    	}
    	return 0;
    }
    

    还是要注意== 和&的优先级

    总结🍊

    这篇博客我们讲解了求一个数二进制中有多少个1的方法,我们要留意unsigned char 和多多理解三种方法,更要坚持使用第三种方法。

    最后如果这篇博客有帮助到你,欢迎点赞关注加收藏

    在这里插入图片描述在这里插入图片描述
    如果本文有任何错误或者有疑点欢迎在评论区评论
    在这里插入图片描述

    在这里插入图片描述

    • 9
      点赞
    • 15
      收藏
      觉得还不错? 一键收藏
    • 打赏
      打赏
    • 1
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    He XIAO xia

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值