实现简单的a+b
说明
a和b都是 32位
整数么?
- 是的
我可以使用位运算符么?
- 当然可以
样例
如果 a=1
并且 b=2
,返回3
。
挑战
显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?(不使用 "+" 等算数运算符)
当然, 我们的目标就是这个挑战.
如果是有基础的小伙伴, 一定会瞬间想到, 我们可以使用位运算啊, 对, 我们就要是用位运算来解决这个问题.
我将会通过三个例子来分析如何推算出计算过程的.
//我们如何知道需要进位呢? 1+1
/*
A: 0000 0001
B: 0000 0001
我们需要得知这么一个情况, 就是什么时候我们需要进位, 当然, 在二进制中, 满2进1,
我们需要标记这种情况
在三种按位运算符(&, |, ^)中, 显然 A & B 符合这种情况
A & B: 0000 0001
当 A 和 B某一位相同的时候(都是1), 那么下次计算的时候就需要进位
*/
//那么我们怎么知道无需进位呢? 1+2
/*
A: 0000 0001
B: 000000010
当我们进行 A & B 操作后我们发现:
A & B: 0000 0000
也就是 A & B == 0 的时候, 这时候根本不需要进位
*/
//无需进位的时候,我们怎么得到结果呢? 1+2
/*
A: 0000 0001
B: 0000 0010
当我们 A & B 后发现:
A & B: 0000 0000 => A & B == 0
这时不需要我们进位, 那我我们该如何得出结果呢?
当然是某一位是 1 的时候, 我们需要保存下来, 这时候需要 "^" 运算符发挥它的功效了
我们会得到:
A ^ B: 0000 0011 => 3
这时候我们得到了我们想要的值.
*/
//需要进位的时候, 我们如何的得到结果呢? 1+3
/*
A: 0000 0001
B: 0000 0011
我们首先通过 A & B 得到
A & B: 0000 0001 => 我们得知, 最后一位需要进位
那么我们通过 "<<" 运算符可以得到一个进位后的值 C:
C = (A & b) << 1 => C: 0000 0010
然后我们通过 A ^ B 得到
A ^ B: 0000 0010 => 这是"原值"不需要进位的部分, 我们赋值给D:
D = (A ^ B)
这时候, 我们需要拿已经做了进位操作的 C, 以及之前保留的部分 D 重复以上操作
直到 val_A & val_B == 0 的时候, 就说明计算完成了
*/
最后附上Java版的代码:
//最后附上Java版的代码
public class Solution {
/**
* @param a: An integer
* @param b: An integer
* @return: The sum of a and b
*/
public int aplusb(int a, int b) {
// write your code here
int m_ay = a & b;
int m_yh = a ^ b;
while(m_ay > 0) {
int t_a = m_yh;
int t_b = m_ay << 1;
m_ay = t_a & t_b;
m_yh = t_a ^ t_b;
}
return m_yh;
}
}