题目:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
题目中要求不要加减法实现加法,数据的处理除了四则运算外,最常用的就是位运算。
对于十进制的加法如何计算呢?
比如 266+58,原来的处理方式做个位与个位加,逢10进1。
可以将上述过程拆分开:
第一步:各位相加不进位。(个位6+8=14,只取4,十位5+6=11,只取1,百位2+0=2 )第一步得到值为214
266
58
214
第二步:只取进位。(6+8=14,只取10,十位5+6=11,只取百位的1,即为100,)第二步得到的值为110
第三步:将上述两步值累加求得324。
上述思路与平时的求和类似,只不过将低位与高位的计算分开。
将十进制的计算逻辑运用到二进制,也分三步走
- 各位相加不进位。
- 各位相加只取进位。
- 将一二两步结果相加。
比如5的二进制为101,17的二进制为10001,尝试用三步计算出来
第一步:
10001
****101+
10100
第二步:
10001
***101 +
00010
第三步:
10100
00010+
10110
将10110转化为十进制即为22。
上述过程中,不取进位本质是 二进制位不同的时候为1,相同的时候则为0,这本质是异或运算。
算数 | 结果 |
---|---|
1^1 | 0 |
1^0 | 1 |
0^1 | 1 |
0^0 | 0 |
而只取进位,本质是一种与运算,但是为了表示进位过程,需要将与之后的结果左移。
综上代码如下:
public class Solution {
public int Add(int num1,int num2) {
// 表示和
int sum = 0;
// 表示进位
int carry = 0;
while(num2 != 0){
// 不取进位
sum = num1 ^ num2;
// 取进位
carry = (num1 & num2) << 1;
num1 = sum;
num2 = carry;
}
return num1;
}
}