(位运算)给出两个整数a和b, 求他们的和, 但不能使用 +

431 阅读2分钟

参考链接:blog.csdn.net/sinat_15029…

两个数异或,0对1异或才是1,1对1异或是0,那么相当于数学意义上的相加,但是不算上进位。 两个数与,只有1对1与才是1,可以通过与运算得知上述结果中,哪个位相加有进位。

如果没有进位,那么a|b为正确答案,但是有进位时1|1=0
思想:可以先判断两个数相加是否有进位,如果有进位就忽略进位相加,然后再加上进位值即为正确答案
①判断进位:a&b!=0
②计算进位值:(a&b)<<1
④计算忽略进位的值a^b
③进位加上非进位的值a|b

public int plusByBitOperation(int a, int b) {
    int c = 0, d = 0;
    while((a&b) != 0) {
        c  = a ^ b;
        d  = (a&b) << 1;
        a = c;
        b = d;
    }
    return a|b;
}

分析

这道题是考察对各种位运算组合的熟练度。

我们需要通过练习才能知道哪种位运算在什么情况下能间接达到什么效果。这里就涉及到非常常用的掩码(BitMask)的概念。

Basic

掩码

英文比较好理解,BitMask,位的遮罩,把某些位给遮上,置零。

与运算在数学意义上的作用

判断相加是否包含进位

要判断两个二进制数相加是否有进位,可以用两个数进行与运算,由于与运算 0 和 1 相与为 0,1 和 1 相与才是 1,那么我们可以根据结果是否为0,来判断是否包含进位。

举例:

a = 0001 0001
b = 0000 0101

a & b = 0000 0001 由此可知最低那位相加有进位,因为都是1,相与之后结果才会是1。

异或运算在数学意义上的作用

相当于两个二进制相加,但忽略进位。即两个数进行异或时得出的结果相当于数学意义上的相加,但不包含进位值。 0 ^ 1 = 1, 1 ^ 1 = 0, 0 ^ 0 = 0。