版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liyuefeilong/article/details/51301650
一、题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
输入:
- 输入可能包含多个测试样例。
- 对于每个测试案例,输入为两个整数
a
和b
。
输出:
- 对应每个测试案例,输出m+n的值。
样例输入:
2 // 第一行表示案例的个数
3 4
7 9
样例输出:
7
16
二、题目分析
使用位运算可以解决此问题,在相加时可能需要迭代运算,每一次迭代时,将a+b分解为不计进位的相加结果sum
和进位carry
,每次再将sum
和carry
作为两个新的数,进行相加,直到进位carry == 0
为止,返回sum
。每一步迭代主要是依靠以下步骤来解决即可:
- 考虑两个整型
5
和9
的二进制格式:101
和1001
,其不计进位的相加结果(1101
)取决于两个二进制数对应位上'1'
的个数,使用异或操作:101 ^ 1001 = 1100
,得到sum
; - 考虑两个整型
5
和9
的二进制格式:101
和1001
的进位,我们知道只有两个数对应位上均为’1’,才有进位,因此可使用逻辑与&得到两个数中都为1的二进制位:101 & 1001 = 0001
,由于进位发生在对应位上的高一位,因此对结果0001 << 1 = 0010
,得到进位的结果carry
; - 将前面两步得到的
sum
和carry
再进行迭代相加(相加的时候还有可能再产生进位),直到carry == 0
退出循环。
三、示例代码
int myAdd(long long a, long long b)
{
if (a == 0 || b == 0) return a != 0 ? a : b;
long sum = 0, carry = -1;
while (carry != 0)
{
sum = a ^ b;
carry = (a & b) << 1;
a = sum;
b = carry;
}
// 防止溢出
if (sum > INT_MAX) return INT_MAX;
else if (sum < INT_MIN) return INT_MIN;
else return sum;
}
int main()
{
long long a, b;
cin >> a >> b;
int result = myAdd(a, b);
cout << "The result is: " << result << endl;
system("pause");
return 0;
}