问题描述
不使用运算符 + 和 - ,计算两整数 a 、b 之和。
示例 1:
输入: a = 1, b = 2
输出: 3
示例 2:
输入: a = -2, b = 3
输出: 1
思路
- 很明显,肯定是按位操作,要理解按位操作符的计算规则及意义
- ^:不同的为1,这里作用就是加和,但不进位
- (a&b):就是看有没有进位的,有就进位,操作左移一位,即(a&b)<<1,然后把加和跟进位的加和,即为结果
- 为什么要递归?当加和跟进位加和的时候,可能又有进位的,但^是不进位的,故要再判断一次是否有进位,有的话循环上述步骤,没有即返回。
实现
class Solution {
public int getSum(int a, int b) {
int res =a^b;
int flag=(a&b)<<1;
if(flag!=0){
res= getSum(res,flag);
}
return res;
}
}
示例
极端情况比较能说明问题:
a:0111 1111
b:0000 0001
a^b:0111 1110
(a&b)>>1:0000 0001–》0000 0010
递归:
a:0111 1110
b:0000 0010
a^b:0111 1100(加和过程中又有进位的)
(a&b)>>1:0000 0010–》0000 0100
…递归下去
相关知识点
1.按位取与(&)
两值按二进制位进行 “与”运算
规则:0&0=0;0&1=0;1&0=0;1&1=1
举个栗子: a = 5 ,b = 3
a:0101
b:0011
r:0001
2.按位取或(|)
两值按二进制位进行 “或”运算
规则:0|0=0;0|1=1;1|0=1;1|1=1
举个栗子: a = 5 ,b = 3
a:0101
b:0011
r:0111
3.按位取异或(^)
两值按二进制位进行 “异或”运算
规则:00=0;01=1;10=1;11=0
举个栗子: a = 5 ,b = 3
a:0101
b:0011
r:0110
4.左移运算符“<<”及右移运算符“>>”
左移运算符" << n ":
将一个数的二进制位全部向左移n位,最左边一位舍弃,右边补0。
举个栗子:
a = 5
a<<1
0101 -> 1010
左移一位后,a = a * 2 = 10;
右移运算符">>":
将一个数的二进制位全部向右移n位,最右边一位舍弃,左边补0。
举个栗子:
a = 5
a>>1
0101 -> 0010
左移一位后,a = a / 2 = 2;