476.数字的补数

题目:给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

注意:

  1. 给定的整数保证在32位带符号整数的范围内。
  2. 你可以假定二进制数不包含前导零位

示例 1:

输入: 5
输出: 2
解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。

示例 2:

输入: 1
输出: 0
解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。

第一想到的比较简单的方法就是求这个书的二进制然后取反,本文介绍另一种方法,利用位移和异或运算来实现。因为异或运算的原理就是相同为0,相异为1,可以看到示例1中5这个数字的二进制与2这个数的二进制的每一位做异或运算都是1,因为本身它们每一位都是不同的(2是由5的二进制每一位取反而得)。同理,从5的二进制最后一位开始,对每一位和1进行异或运算就得到了2,过程如下:

  1                 0                  1                        数字5

 ^1               ^1                 ^1                       每一位与1做异或运算

   0                 1                  0                       结果:数字2

代码如下:

    public static int findComplement(int num) {
        int result = 0, i = 0;
        while (num > 0) {
            result += ((num % 2) ^ 1) << i++;   // 要将数字左移回相应的位置上
             num >>= 1;  // 处理完最后一位后要右移一位
        }
        return result;
    }

如代码所示,循环从最后一位开始跟1做异或运算,然后每次往左移一位,直到这个数字的最高位被处理完就可以结束了。

猜你喜欢

转载自blog.csdn.net/luqiren/article/details/82593198