添加两个数字而不使用+后面的实现逻辑?

时间:2015-04-18 23:48:34

标签: java add

我在网上找到了这个代码。但是,我无法得到以下代码背后的逻辑:

public static int add(int a, int b) {
    if (b == 0) return a;
    int sum = a ^ b; // add without carrying
    System.out.println("sum is : "+sum);
    int carry = (a & b) << 1; // carry, but don’t add
    return add(sum, carry); // recurse
}

4 个答案:

答案 0 :(得分:2)

让我们看一个例子(为简单起见使用8位)

  a = 10010110
  b = 00111101

a^b是xor,它为1在一个数字中有1而在另一个数字中有0的地方提供a^b = 10101011 。在我们的例子中:

0 + 0 = 0

0 + 1 = 11 + 0 = 11以来,剩下要处理的唯一列是两个数字都有a^b的列。在我们的示例中,无论

的答案是什么, 00010100 + 00010100 都很短
1 + 1 = 10

是。在二进制, 00101000 ,所以上述总和的答案是

(a & b) << 1

a^b。因此,(a & b) << 1a + b的总和与sum相同。

因此,假设该过程保证终止,答案将是正确的。但是该过程将终止,因为每次我们递归调用0时,由于位移<<,第二个参数在末尾至少还有一个0。因此,我们保证最终得到完全由if (b == 0) return a; s组成的第二个参数,以便行{{1}}可以结束该过程并给我们一个答案。

答案 1 :(得分:1)

我们正在添加将整数转换为位并使用按位运算符。

EXOR即^:0 ^ 0和1 ^ 1 = 0,其他情况给出1。

AND即&amp; 1 ^ 1 = 1,..其他情况给出0。

&LT;&LT;或左移。即向左移动并追加0位:0010变为0100

例如。

add(2,3)

2= 0010
3=0011

exor both : to get initial sum :  0001

carry : a &b = 0010  

Left shift by 1 bit : 0100 i.e 4

add(1,4)

exor both : 0001 0100 and u get 0101 i.e 5

carry = 0000 <<1 i.e 0000 .. 

因为进位为0,它会停止加法并返回前一个和

答案 2 :(得分:1)

例如,考虑5+7

5     = 101 (Base 2)
7     = 111 (Base 2)

现在考虑添加两个(基数2)数字:

0+0 =  0 = 0 carry 0
1+0 =  1 = 1 carry 0
0+1 =  1 = 1 carry 0
1+1 = 10 = 0 carry 1

A+B的总和(不携带)为A^B且进位为A&B;当你带一个数字时,它会向左移一位数(因此(A&B)<<1)。

所以:

5    =  101 (Base 2)
7    =  111 (Base 2)
5^7  =  010 (sum without carrying)
5&7  = 101  (the carry shifted left)

然后我们可以递归来添加进位:

A    =   010
B    =  1010
A^B  =  1000 (sum without carrying)
A&B  = 0010  (the carry shifted left)

然后我们可以再次递归,因为我们还有更多要携带的东西:

A'    =  1000
B'    =   100 (without the leading zeros)
A'^B' =  1100 (sum without carrying)
A'&B' = 0000  (the carry shifted left)

现在没有东西可以携带 - 所以我们可以停下来,答案是1100 (base 2) = 12 (base 10)

算法只是实现十进制加法作为(longhand)二进制加法,使用or来添加,并使用位移and来查找进位并将递归,直到没有其他东西可以携带(这将始终发生,因为bitshift每次向进位附加另一个零,因此每次递归至少再多一位不会每次都生成进位值。

答案 3 :(得分:0)

这是补充表:

+   0  1
   -- --
0 | 0  1
1 | 1 10
      ▲

如果忽略进位,您会发现它与XOR表相同:

^   0  1
   -- --
0 | 0  1
1 | 1  0

因此,如果将两个数字与按位XOR组合在一起,则无需进位即可逐位添加。

现在,携带什么?只有在两个输入均为1时才会出现这种情况。

您可以使用AND:

获得
&   0  1
   -- --
0 | 0  0
1 | 0  1

但是,在将一个位置向左移动之后,需要将其添加到总和中,因为它带有&#34;#34;结束,因此(a & b) << 1

因此,您可以在不携带和携带本身的情况下计算加法。如何在不添加的情况下将它们添加到一起?简单!通过递归这个加法的定义!

请参阅@ pbabcdefp关于递归总是终止的原因的答案。