两个32位的int类型的数据不同的Bit位有多少个?
A:分析:
1)说白了,就是转换成二进制数之后,看有多少个位数上的值不同
举例:1,2
1-----:00000000 00000000 00000000 00000001
2-----:00000000 00000000 00000000 00000010 结果为:2个bit位不同
2)这里我们首先想到的就是位异或^(不同为1---心法:同性相斥,异性相吸),1^2=3
转换为二进制:00000000 00000000 00000000 00000011
然后统计1的个数,很明显,两个,那结果就是2
3)但如果两个数中出现负数怎么办?
举个例子:-1,-2
-1----:10000000 00000000 00000000 00000001
-2----:10000000 00000000 00000000 00000010 结果应为2,但如果位异或一下呢?
下面:自己可以写个测试代码测试下-1,-2的位异或
经计算:-1 ^ -2 = 1,,,这样按照2)输出结果应该为1呀,所以,位异或就不能直接用了
为什么呢?
a:首先我们要知道,计算机底层对数据进行计算,都是通过二进制补码进行的
b:在这里,正数的原码、反码、补码相同,所以2)直接用没问题
c:负数的反码为原码的对位取反(最高位符号位不变),反码再加1得到补码
d:补码求位异或,得出的也是补码,现在里面的1代表的是补码中不同的位数
e:然后再求反码和原码,得勒,1变0,0变1,全乱套了,这时候你还敢数1么
好了,经过这么几次的折腾,我们是求出来位异或了,但我们的最终目的是看多少个位不同
这下好嘛,经过一系列的倒腾,谁敢保证位异或的值里面的1就是不同的地方
4)所以嘛,我们要改进一下,就是不管正和负,我们在计算位异或的时候都取绝对值
Java中取绝对值的方法:Math.abs(数值);
a:假如都为负数,那直接取绝对值就行了,负数变正数,仅仅最高位的符号位从1变成了0
其他的值都不变,所以嘛,取绝对值直接用2)
b:如果一正一负,把负的变成正的,也就是最高位符号位从1变成0,其他值不变
但这得注意,本来最高位一个1一个0,不同
转变后现在相同,所以计数器得先+1,再取绝对值执行2)
5)现在,正负问题解决了,下来就该考虑统计1的问题
按正常思路,肯定想的是转换成二进制,再统计,但转换二进制很麻烦,我们换个思路:
十进制转换二进制的方法,就是除以2,取余数的过程
在这里,我们目的是统计1,而不是得到二进制数,所以我们就把重点放在这个过程上
a:将位异或结果对2取余——%
b:若为1,计数器+1,然后位异或的结果再对2取整——/
c:判断b的结果是否大于1,若为true,继续执行a,为false,结束,
d:输出计数器结果
B:现在根据分析,实现算法
这下,我们就可以自行输入几组不同符号的数据,测试代码的正确性了