题目要求:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
分析:
不使用运算符号,则需要使用逻辑位运算符号如&,|,!,>>,<<,^,等等
计算机中正整数存储为其原码,
负数存储为其补码=原码求反码+1,
首先分析两个正数求和,如11+13=24
11=0000 0000 0000 0000 0000 0000 0000 1011,
13=0000 0000 0000 0000 0000 0000 0000 1101,
24=0000 0000 0000 0000 0000 0000 0001 1000,
注意到上式有进位,因此可以将两数和分为两部分:进位部分和无进位部分
11+13的无进位为:1000,进位为:0000 0000 0000 0000 0000 0000 0001
要实现此方法
首先分析各位运算符的作用:
操作数 1 | 操作数2 | 与 | 或 | 异或 |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
其次分析是否需要进位的情况
操作数 1 | 操作数2 | 进位 | 无进位 |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
观察以上两表,可以看出与运算求得进位部分,异或求得无进位的部分,注意:进位部分需要左移一位;
如下所示:
11= 0000 0000 0000 0000 0000 0000 0000 1011,
13= 0000 0000 0000 0000 0000 0000 0000 1101
11&13 = 0000 0000 0000 0000 0000 0000 0000 1001 左移一位得到:
= 0000 0000 0000 0000 0000 0000 0001 0010
11^13 = 0000 0000 0000 0000 0000 0000 0000 0110
但通过与和异或得到的值简单的或将其结合并不能得到正确的解,如下:
(11&13)|(11^13)=0000 0000 0000 0000 0000 0000 0001 0110=22,缺少一个这个过程中的进位,如此需要循环直到没有进位为止,
因此需要判断两个数需要不需要进位,通过观察规律,得到当与运算时有1则需要进位,
代码实现
public static int add(int num1,int num2){
int sum1 = 0;
int sum2 = 0;
int sum = 0;
while((num1&num2)!=0){
sum1 = (num1&num2)<<1;
sum2 = num1^num2;
num1 = sum1;
num2 = sum2;
}
sum = num1|num2;
return sum;
}