能否不使用加减乘除而实现两数的相加呢?
当然可以,接下来将以最简单的方式理解用位运算实现两数相加。
首先,十进制的加法大家都非常熟悉,下面我们将十进制的加法进行解析,可分为下面这三步:
- 将数字的各位分别相加,先不管进位的问题
- 计算产生进位的数字
- 把上面两步的结果进行相加
例如:
- 12 + 15
- 个位和十位数字相加,先不管进位的问题:2 + 5 = 7(个位相加),1 + 1 = 2(十位相加),所以结果为27
- 由于没有产生进位所以结果为0
- 相加得到结果:27 + 0 = 27
- 99 + 111
- 各位数字分别相加,忽略进位的问题:9 + 1 = 0(个位),9 + 1 = 0(十位),0 + 1 = 1(百位),所以结果为100
- 计算产生进位的数字:1 + 9 = 10,10 + 90 = 100,得到进位之后的结果为10 + 100 = 110
- 相加得到结果为:100 + 110 = 210
然后,我们运用二进制相加的时候,也可以使用上面那三步,只要用二进制进行转换即可
例如:
- 1100(12) + 1111(15)
- 各位数字分别相加,忽略进位的问题,可以得到1100 + 1111 = 0011
- 计算产生进位的数字:0100 + 0100 = 1000,1000 + 1000 = 10000,得到进位结果1000 + 10000 = 11000
- 相加得到结果为:0011 + 11000 = 11011(27)
相信大家可以发现第一步和第二步都可以转化为位运算,即:
第一步可以用异或(相同为0,相异为1)实现,
第二步可以先进行相与(两位全为1,结果才为1)再左移一位实现,
到第三步大家会发现又变成二进制的加法了,所以我们接下来需要循环前两步,用一张图进行说明
这里我们需要考虑一直循环步骤一、二,什么时候结束?那就是当进位为0的时候就可以结束,此时结果就是不考虑进位时的结果,不需要在于进位(0)进行相加,计算即可结束
使用代码来表示就是:
public int add(int a, int b){
while(b != 0){ // 循环判断,当进位为0时不再进行循环
int c = a ^ b; // 各位数字分别相加,忽略进位的问题;通过异或的方式实现
int d = (a & b) << 1; // 计算产生进位的数字;通过相与和左移一位实现
a = c;
b = d;
}
return a;
}