赞
踩
不使用运算符 + 和 - ,计算两整数 a 、b 之和。
示例 1:
输入: a = 1, b = 2
输出: 3
示例 2:
输入: a = -2, b = 3
输出: 1
分析:
二进制的加法有以下几种情况,
1+1 = 0 (有进位)
1+0 = 1 (无进位)
0+0 = 0 (无进位)
0+1 = 1 (无进位)
在不考虑进位的情况下,就是二进制的异或操作。所以,就可以把加法分成无进位的异或结果a^b
,其与保存的进位相加,循环直到没有进位为止,就可以得到结果了。
再分析二进制加法中进位怎么能保存,因为只有 1+1的时候会产生进位,就是与操作a&b
,但是进位需要在更高的一位,所以就左移一位,c = (a&b)<<1;
这样,进位就可以保存了
可以用 a = (a^b) ^ c
得到一轮结果 ,但是有可能还会有进位,所以需要将这个放在循环里面。
while (b)
{
// 记录a+b的进位,直到进位为0是退出
int carry = ((unsigned int ) (a & b))<<1 ;//(unsigned int)代表符号位也进行运算
a = a^b; //结果相加
b = carry; //循环
}
return a;
至于为什么这个方法负数同样适用,就得益于补码的这个特点,它消除了加法中的符号特性,计算机可以直接对数进行二进制加,结果再利用补码存储。
上面的用异或和与操作一起模拟的,实现的就是二进制加法的过程;保证结果正确的,是补码本身。
LeetCode上代码:
class Solution {
public:
int getSum(int a, int b) {
while (b)
{
int carry = ((unsigned int ) (a & b))<<1 ; // 记录a+b的进位,直到进位为0是退出
a = a^b; //结果相加
b = carry; //循环
}
return a;
}
};
我在VS上面实现的代码:
#include<iostream> #include<string> using namespace std; int getSum(int a, int b) { while (b) { int carry = ((unsigned int ) (a & b)) << 1; a ^= b; b = carry; } return a; } int main() { int a = 0; int b = 0; cout << "请输入第一个数字" << endl; cin >> a ; cout << "请输入第二个数字" << endl; cin >> b; int sum = getSum( a , b); if (a >= 0 && b >= 0) { cout << a << "+" << b << "=" << sum << endl; } else if(a<0 && b<0) { cout << "(" << a << ") + (" << b << ") =" << sum << endl; } else if (a<0) { cout << "(" << a << ") + " << b << " =" << sum << endl; } else { cout << a << "+ (" << b << ") =" << sum << endl; } system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。