剑指 Offer 15. 二进制中1的个数
这道题目是求整形数字的二进制中1的个数,并且符号位也计算在内,就是把数字作为无符号的整形处理。
这题有三种以上的做法,第一种是把每一位二进制上的数字与1做&运算后的结果加起来,将n右移一位,java的无符号的右移是>>>
代码如下:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while (n!=0) {
res += n&1;
n>>>=1;
}
return res;
}
}
第二种做法是n不断与(n-1)做&运算,这样就可以把n的最低一位1变为0,示例如下
n: 100100
n-1:100011
经过&运算之后,后三位就会全变为0
当不为0时,重复之前的做法并计数
代码:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while (n!=0) {
res++;
n&=(n-1);
}
return res;
}
}
第三种做法就是,n&(-n)可以取出n的最后一位1,例如二进制数1110010,经过运算可以得到最低位的1为10,让1110010减去10得1110000,不断把末尾1减去并计数即可得到结果
代码:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while (n!=0) {
res++;
n-=n&(-n);
}
return res;
}
}
8位有符号数的范围是-128~127
规定(维基百科-补码词条):
负数的补码 = 该负数的绝对值按位取反 + 1
则补码 1000 0000 ,减一得 0111 1111,按位取反即为128,即该补码对应的值为-128
总结:
- byte 占用一个字节, 8 位,对于计算机来说表数范围为 0000 0000 ~ 1111 1111
- 最高位表示符号位
- 计算机用补码表数
- 正数和0的补码 = 源码
- 负数的补码 = 该负数的绝对值按位取反 + 1