嗨,当你看到这篇文章,并且点了进来,那是我的荣幸,也没什么好感谢你的,那么就祝福屏幕前的你,未来offer拿到手软!!!
好了,一波吹嘘完,我们开始干正事。
目录
题目主题:统计一个数二进制位中1的个数
一,方法一
1.1,代码
1.2,原理解析
二,方法二
2.1,代码
2.2,原理解析
2.3,代码优化
三,方法三
3.1,代码
3.2,原理解释
题目主题:统计一个数二进制位中1的个数
注意:这里的二进制位指的是二进制补码,因为数在计算机中存储都是以二进制补码的形式存储
一,方法一
1.1,代码
#include<stdio.h>
int Numberof1(int n) {int count = 0;for (int i = 0;i < 32;i++) {if (((n >> i) & 1) == 1) {count++;}}return count;}
int main() {int n = 0;scanf("%d", &n);int ret = Numberof1(n);printf("%d的二进制中1的个数为%d\n", n, ret);return 0;
}
1.2,原理解析
二,方法二
2.1,代码
int Numberof1(int n) {int count = 0;while (n != 0){if ((n % 2) == 1) {count++;}n /= 2;}return count;}
int main() {int n = 0;scanf("%d", &n);int ret = Numberof1(n);printf("%d的二进制中1的个数为%d\n", n, ret);return 0;
}
2.2,原理解析
但是,还没完,当你输入一个复数的时候,完蛋,程序达不到目的了.........
不慌,发现问题就解决问题。我们输入的一个十进制数,统计其二进制位1的个数,对于正数而言,它的原码,反码,补码都是一样的,但是负数的原码补码不一样,所以坏就坏在一个负号上,那我们的解决方法就是将这个输入的数不管你输入的正负与否,全部转换为unsigned int 类型。当你输入的是正数时,就和上面代码一样的处理机制,毫无影响。如果输入的是负数,我们将其转换为无符号数之后,它在计算机中的存储的是没变的,但是我们在计算的时候,就会以其补码为基准,认为它是一个无符号的,转换成十进制就是一个很大很大的数(你可以理解为是很大的正数,但实际是无符号的),那你拿着这个很大很大的十进制数,去模2除2,最终统计的也就是其对应的二进制补码中1的个数。
2.3,代码优化
int Numberof1(unsigned int n)//其余代码一样,就只是函数形参用unsigned int 类型
其实这里没必要想那么多,在计算机中,无论正负数都是以补码存储,对于底层而言,数据的正负是没有意义的,只有到了高层的应用程序才有区分,所以负数转换成无符号数,就是强行的就把它的补码当作原码,以这个原码对应的十进制数来统计二进制位的1的个数。
三,方法三
3.1,代码
int Numberof1(int n) {int count = 0;while (n) {n = n & (n - 1);count++;}return count;}
int main() {int n = 0;scanf("%d", &n);int ret = Numberof1(n);printf("%d的二进制中1的个数为%d\n", n, ret);return 0;
}
3.2,原理解释
核心原理就是 : n & (n - 1)
这里也就是说,我们每按位与一次,就会去掉一个1,所以在n变为0之前,只要统计执行了几次按位与,那么它的二进制位中就有几个1
好了,今天的分享就只有这么多,只有一点小归纳,如果大家发现有知识错误的话,请帮忙及时指出,十分感谢,也请大家帮忙多多点赞评论,这将会督促我前行,大家一起加油!!!