5

I was asked this question on the interview. I didn't answer and actually I don't understand how it works.

int add(int x, int y)
{
    while (y != 0)
    {
        int carry = x & y;  
        x = x ^ y; 
        y = carry << 1;
    }
    return x;
}

I'm not asking why does it produce a correct answer... First of all, why does the algorithm eventually stop? To me it's not that obvious.

In order for it to stop, carry has to become 0. Can't someone explain it in a nutshell?

Alupkers
  • 223
  • 1
  • 9
  • 11
    It's a [full adder](https://en.wikipedia.org/wiki/Adder_%28electronics%29#Full_adder). After you shift left 32 times, there will be 32 zero bits (which is `0`). – Elliott Frisch May 26 '16 at 03:57
  • @ElliottFrisch Well... yes)). But it's not explained why it works. – Alupkers May 26 '16 at 04:02
  • 2
    @Alupkers You asked why algorithm stops? Exactly as @ElliottFrisch said: `curry << 1` sets the right-most bit to 0. In at most 32 steps (integers are 32 bit wide in Java) all bits are 0 so `y==0` and the loop ends. – Nikem May 26 '16 at 04:13

3 Answers3

6
line 1 : int carry = x & y;

line 2 : x = x ^ y;

line 3 : y = carry << 1;

if x = 1; y = 2;

Binary for each number:

0 = 00

1 = 01

2 = 10

3 = 11

for line 1 code,

& (bitwise AND) Binary AND Operator copies a bit to the result if it exists in both operands

x is 1 => 01

y is 2 => 10

result carry is => 00 (0)

for line 2 code,

^ (bitwise XOR) Binary XOR Operator copies the bit if it is set in one operand but not both.

x is 1 => 01

y is 2 => 10

result x is => 11 (3)

for line 3 code, variable carry needs to shift left for 1 bit, so now carry is 0 => 00 and shift 1 bit left means carry is now 0. The result y is (0). And while loop stop because y is 0 now.

The final result for x is 3.

Hope this will help you.

Erika Kay
  • 145
  • 7
  • `x & y` is bitwise and, not logical and. carry will still be 0 here, but for entirely different reasons than you stated. – cf- May 26 '16 at 04:34
2

Let's take an example:

x=13(1101)
y=9(1001)

Loop 1:
-----------------
y!=0 -> carry=(1101)&(1001)=1001(9)  [AND Op]
x=(1101)^(1001)=0100(4)   [XOR Op]
y=carry<<1 -> y=(carry)x2=10010(18)

Loop 2:
-----------------
y!=0 -> carry=(0100)&(10010)=00000(0)
x=(0100)^(10010)=10110(22)
y=carry<<1 -> y=0

loop terminated.

therefore,x is 22.So,x^y store the sum part and x&y store the carry part,and then carry(x&y) is shifted to match the digit with x^y,and finnally XOR them and store into x. x is the resultant.

Hailey
  • 157
  • 1
  • 18
1

In a nutshell its about using y (and the "carries/x&y" it becomes) to modify x until it becomes the sum of both ints. For example,

y=1 (....0001), x=anything (either .....0 or .....1)
if x ends with 0, x&y=0
    //x^y = x becomes ....001 (thereby adding 1)
    //since x&y=0 the loop stops
if x ends with 1, x&y=1
    //x^y = x
    //since y= x&y<<1, new y=(.....000010)
    if x ends with 01, x&y=0
        //x^y = x becomes ....010 (thereby adding 1)
        //since x&y=0 the loop stops
    if x ends with 11, x&y=1
        //x^y = .....01
        //since y= x&y<<1, new y=(......000100)
        if x ends with 011
            //stuff happens and x becomes ....100 (thereby adding 1)
            //loop stops
        if x ends with 111
            //...
            //if x ends with 111111, x becomes ....1000000 (thereby adding 1)
            //if x ends with 1111111, x becomes ....10000000 (thereby adding 1)
            //if x ends with 11111111, x becomes ....100000000 (thereby adding 1)
            //well you get the idea

The same logic is applicable to all values of y, and is not that much different from normal addition only that there are now 2 possible digits (0 and 1) instead of the usual 10 (0 to 9).

Poh Zi How
  • 1,489
  • 3
  • 16
  • 38