根据题目要求,我们要把num二进制的每一位取反后输出,但是在计算机的存储过程中并不仅仅是存储有效的二进制位数,例如5的二进制位是101,但是计算机要凑齐特定的位数,在使用32位整数存储时存的是:0000 0000 0000 0000 0000 0000 0000 0101
所以我们首先要处理的就是如何找到一个数字二进制的最高位1在第几位
找到之后就是各位取反了,取反可以用掩码与原数字亦或运算。掩码就是与原数字相同的位数但是全1,例如5:101,我们可以用111与101亦或,掩码111可以用2^i-1求得,i就是原数字的位数。
public static int findComplement(int num) {
//先要找到数字二进制的最高位
int highbit = 0;
for (int i = 1;i<=30;i++){
if(num >= (1<<i)){
highbit = i;
}
else
break;
}
int mask = (highbit == 30?0x7fffffff : (1<<(highbit+1))-1);//制造掩码
return num ^ mask;
}
这里的掩码注意是2^(highbit+1),原因要看程序if中的判断,当本次玄幻取i时,比较的二进制是
i+1位的二进制(如:i=1时候比较的是10B,这里10是两位,而里面赋值确实i=1),所以取一共多少位的时候还要+1。
最后还要考虑掩码的越界问题,用了一个三目运算,当给的num位数到了整数存储最高位时候,掩码就不能用上面的公式计算了,直接赋值0x7fffffff(二进制位全是1)即可。
最后求亦或即可。