力扣476-数字的补数

 根据题目要求,我们要把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)即可。

最后求亦或即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值