lintCode第一题A+B问题
http://www.lintcode.com/zh-cn/problem/a-b-problem/
问题:
给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。
注意事项
你不需要从输入流读入数据, 只需要根据aplusb的两个参数a和b, 计算他们的和并返回就行。
您在真实的面试中是否遇到过这个题?
说明
a和b都是 32 位 整数么?
是的
我可以使用位运算符么?
当然可以
样例
如果 a = 1 并且 b = 2, 返回3
涉及知识点: javascript中的位操作符,参考资料 javascript高级程序设计
- 按位非(NOT)
按位操作的本质:操作数的负值减1。用~表示 - 按位与(AND)
(&)表示。两个操作数先转为二进制,比较二进制中的每一位数,如果两个都是1,则返回1。其中任何一位是0,结果都是0
例如:
var result = 25&3;
底层操作为:(最后8位)
25:0001 1001
3:0000 0011
&:0000 0001
返回 1 - 按位或(OR)
(|)表示。两个操作数先转为二进制,比较二进制中的每一位数,如果有一个位是1的情况下返回1,而只有在两个位都是0的情况下才返回0
例如:
var result = 25|3;
底层操作:(最后8位)
25: 0001 1001
3: 0000 0011
|: 0001 1011
返回27 - 按位异或(XOR)
(^)表示。 两个操作数先转为二进制,比较其中的每一位数,只有两个数值对应位上只有一个1是才返回1,否则返回0,即两位都是1或都是0的情况下,返回0
例如:
var result = 25^3;
底层操作:(最后8位)
25: 0001 1001
3: 0000 0011
^: 0001 1010
返回26 - 左移
(<<)表示。这个操作符会将所有位向左移动指定的位数。
例如:
var oldValue = 2;
var newValue = oldValue<<5;
底层操作:(最后8位)
oldValue: 0000 0010
newValue: 0100 0000
返回64 - 有符号的右移
(>>)表示。操作符会将数值向右移动,并保留符号位(即正负号标记)。与上个例子相反 - 无符号右移
(>>>)表示。 这个操作符会将数值的所有32位都向右移动。正数无符号右移和有符号右移相同。负数为,这个数先取反再向右移,右移的空位由0来填充
分析:
例如 7+18
十进制 7+18 首先不考虑进位 为 7+8,得到5.第二步考虑进位 进位为1,得到10.结果相加为25
同理二进制也是按这个方法
二进制:
7: 0000 0111
11:0001 0010
- 7的二进制与11的二进制相加不考虑进位 即 0001 0101.
- 考虑进位的问题 0000 0010 因为只有最后两位进位,所以向左移动一位 0000 0100
- 再次调用第一个步骤 0001 0101 与 0000 0100 相加不考虑进位: 0001 0001
- 调用第二步 只有 0000 0100 发生了进位 向左移动一位 0000 1000
- 在调用第一步 0001 0001 与 0000 1000 相加 0001 1001 进位为0 结果转为十进制为25
具体代码:
const aplusb = function (a, b) {
let sumX = 0
let sumY = 0
do {
sumX = a ^ b
sumY = (a & b) << 1
a = sumX
b = sumY
console.log(a, b)
} while (sumY !== 0)
return sumX
}
console.log(aplusb(7, 18))//测试代码