不使用加减运算符,那就是位运算吧
a&b得到每一位的进位, a ^ b是无进位的相加. 让无进位相加的结果与进位不断的异或, 直到进位为0。
低位 = a^b,进位 = a & b。将低位与进位相加,即可得到两数相加的实际结果。需要注意的是:低位与进位相加有可能再次造成进位,所以需要迭代处理,直到不再产生新的进位为止。
class Solution {
public:
int getSum(int a, int b) {
if(a == 0) return b;
if(b == 0) return a;
//int的符号位在左移的时候,可能会异常,因为signed符号位一定会保留
unsigned int low = 0, carry = 0; //低位和进位
while(true){
low = a ^ b;
carry = a & b;
if(carry == 0) break;
a = low;
b = carry << 1;
}
return low;
}
};
换种写法
class Solution {
public:
int getSum(int a, int b) {
while(b){
auto carry = ((unsigned int)(a&b)) << 1;
a ^= b;
b = carry;
}
return a;
}
};
递归的写法:
class Solution {
public:
int getSum(int a, int b) {
if(!(a&b)) return a^b;//进位为0,返回异或结果
return getSum(a^b, ((unsigned int)(a&b)) << 1);
}
};
多说一句,如果是减法怎么办呢?
计算二进制相反数的规则是“取反加一”:
为什么计算二进制相反数的规则是“取反加一”(转) - 酒鬼z - 博客园
减法相当于加上这个数的相反数,a的相反数为 ~a+1