方法一:
举个例子,对“10”分析,它的二进制形式是1010
单纯对10本身分析,给10%2后看它能得到几个1,这也是一般十进制转化为二进制的过程:
我们进行代码实现:
这样一个简单的算法就写好了,可是仔细想想还是有地方有问题,int整形变量是有范围的,如果输入的值的范围超过的int整形变量的范围,比如我们输入一个负数,那程序就报错了,我们怎么解决这个问题呢,接下来看方法二从本质上分析。
方法二:
我们拿 -1 举例,-1在内存中的存储形式是-1的补码
10000000000000000000000000000001 ---- 原码
1111111111111111111111111111111111110 ---- 反码
1111111111111111111111111111111111111 ---- 补码
我们把1的补码写出来
000000000000000000000000000000001
我们将1的补码与-1的补码进行按位与计算
得到0000000000000000000000000000001 = 1
这样就确认了 最后一位数字是1
然后我们在用>>移位操作符把-1的补码向右移动一位得到
01111111111111111111111111111111111111
我们在把这个补码与1的补码进行按位与计算得到
00000000000000000000000000000000001 = 1
这样我们又确认了-1的倒数第二位的数字是1
然后再往右位移 这样我们算法思路就出来了
接下来代码实现:
方法三:
还有没有更高级的算法呢,当然有,不过这种算法难以让人想到。
n = n & (n - 1)
举个例子
n(1) = 13 ---- 1101
n(1)-1=12 ---- 1100
n(2) = 1100
n(2) -1 = 1010
n(3) = 1000
我们可以发现 每当进行这个算式一次,1都被消除一个,这样一个更高级的算法思路就出来了。
我们进行代码实现:
scanf函数这里的波浪线是编译器导致的,语句都没有错误,大家参考一下。
我所知道的方法大概就这些,以后发现更高级的算法会及时分享给大家的。