371. Integer sum

int getSum(int a, int b) {
  // unsigned: left-shifting a negative int is undefined behaviour
  unsigned sum = a ^ b, carry = (unsigned)(a & b) << 1;

  while (carry != 0) {
    unsigned tmp = (sum & carry) << 1;
    sum ^= carry;
    carry = tmp;
  }

  return sum;
}
class Solution {
public:
  int getSum(int a, int b) {
    unsigned sum = a ^ b, carry = (unsigned)(a & b) << 1;

    while (carry != 0) {
      unsigned tmp = (sum & carry) << 1;
      sum ^= carry;
      carry = tmp;
    }

    return sum;
  }
};
package bitmanipulation

func getSum(a int, b int) int {
    // Go's int is 64-bit: work in uint32 so the carry dies after bit 31
    sum, carry := uint32(a)^uint32(b), (uint32(a)&uint32(b))<<1

    for carry != 0 {
        tmp := (sum & carry) << 1
        sum ^= carry
        carry = tmp
    }

    return int(int32(sum))
}
class Solution {
    public int getSum(int a, int b) {
        // Java ints wrap on overflow, so no unsigned type is needed
        int sum = a ^ b, carry = (a & b) << 1;

        while (carry != 0) {
            int tmp = (sum & carry) << 1;
            sum ^= carry;
            carry = tmp;
        }

        return sum;
    }
}
/**
 * @param {number} a
 * @param {number} b
 * @return {number}
 */
var getSum = function (a, b) {
  // bitwise ops work on int32, so the carry dies after bit 31
  let sum = a ^ b, carry = (a & b) << 1;

  while (carry !== 0) {
    const tmp = (sum & carry) << 1;
    sum ^= carry;
    carry = tmp;
  }

  return sum;
};
class Solution:
    def getSum(self, a: int, b: int) -> int:
        # Python ints are unbounded: mask to 32 bits so the carry dies after bit 31
        M = 0xFFFFFFFF
        total, carry = (a ^ b) & M, ((a & b) << 1) & M

        while carry != 0:
            tmp = ((total & carry) << 1) & M
            total ^= carry
            carry = tmp

        # reinterpret the 32-bit pattern as signed
        return total if total <= 0x7FFFFFFF else ~(total ^ M)
impl Solution {
    pub fn get_sum(a: i32, b: i32) -> i32 {
        // u32: shifts on unsigned values drop high bits without panicking
        let (a, b) = (a as u32, b as u32);
        let (mut sum, mut carry) = (a ^ b, (a & b) << 1);

        while carry != 0 {
            let tmp = (sum & carry) << 1;
            sum ^= carry;
            carry = tmp;
        }

        sum as i32
    }
}