先用1位数的加法来进行,在不考虑进位的基础上,如下
- 1 + 1 = 0
- 1 + 0 = 1
- 0 + 1 = 1
- 0 + 0 = 0
很明显这几个表达式可以用位运算的“^”来代替(异或:相同为0不同为1),如下
- 1 ^ 1 = 0
- 1 ^ 0 = 1
- 0 ^ 1 = 1
- 0 ^ 0 = 0
这样我们就完成了简单的一位数加法,那么要进行二位的加法,这个方法可行不可行呢?肯定是不行的,矛盾就在于,如何去
获取进位?要获取进位我们可以如下思考:
- 0 + 0 = 0
- 1 + 0 = 0
- 0 + 1 = 0
- 1 + 1 = 1
- //换个角度看就是这样
- 0 & 0 = 不进位
- 1 & 0 = 不进位
- 0 & 1 = 不进位
- 1 & 1 = 进位
正好,在位运算中,我们用“<<”表示向左移动一位,也就是“进位”。那么我们就可以得到如下的表达式
- //进位可以用如下表示:
- (x&y)<<1
到这里,我们基本上拥有了这样两个表达式
- x^y //执行加法
- (x&y)<<1 //进位操作
我们来做个2位数的加法,在不考虑进位的情况下
- 11+01 = 100 // 本来的算法
- // 用推算的表达式计算
- 11 ^ 01 = 10
- (11 & 01) << 1 = 10
- //到这里 我们用普通的加法去运算这两个数的时候就可以得到 10 + 10 = 100
- //但是我们不需要加法,所以要想别的方法,如果让两个数再按刚才的算法计算一次呢
- 10 ^ 10 = 00
- (10 & 10) << 1 = 100
现在使用程序实现
private int add(int a, int b)
{
int result = a^b;
int jw = (a&b)<<1;
while(jw != 0) //不需要进位,则说明result里存的已经是正确结果了
{
int tempA = result;
int tempB = jw;
result = tempA^tempB;
jw = (tempA&tempB)<<1;
}
return result;
}
测试: @Test
public void addTest()
{
int a = 5;
int b = 2;
int ans = add(a,b);
System.out.println(ans);
}
结果为:7
证明:a^b是不考虑进位时加法结果。当二进制位同时为1时,才有进位,因此 (a&b)<<1是进位产生的值,称为进位补偿。将两者相加便是完整加法结果。