问题补充:
说明
a和b都是
32位
整数么?
- 是的
我可以使用位运算符么?
- 当然可以
样例
如果
a=1
并且b=2
,返回3
挑战
显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?
java中的位运算
在Java里面,位运算对应运算符如下:
位运算 | 运算符 |
---|---|
与 | & |
或 | | |
异或 | ^ |
非 | ! |
左移位 | << |
右移位 | >> |
Java运算符优先级
序列号 |
符号 |
名称 |
结合性(与操作数) |
目数 |
说明 |
1 |
. |
点 |
从左到右 |
双目 |
|
( ) |
圆括号 |
从左到右 |
|
|
|
[ ] |
方括号 |
从左到右 |
|
|
|
2 |
+ |
正号 |
从右到左 |
单目 |
|
- |
负号 |
从右到左 |
单目 |
|
|
++ |
自增 |
从右到左 |
单目 |
前缀增,后缀增 |
|
- - |
自减 |
从右到左 |
前缀减,后缀减 |
||
~ |
按位非/取补运算 |
从右到左 |
单目 |
|
|
! |
逻辑非 |
从右到左 |
单目 |
||
3 |
* |
乘 |
从左到右 |
双目 |
|
/ |
除 |
从左到右 |
双目 |
整数除法:取商的整数部分,小数部分去掉,不四舍五入 |
|
% |
取余 |
从左到右 |
双目 |
|
|
4 |
+ |
加 |
从左到右 |
双目 |
|
- |
减 |
从左到右 |
双目 |
|
|
5 |
<< |
左移位运算符 |
从左到右 |
双目 |
|
>> |
带符号右移位运算符 |
从左到右 |
双目 |
|
|
>>> |
无符号右移 |
从左到右 |
双目 |
|
|
6 |
< |
小于 |
从左到右 |
双目 |
|
<= |
小于或等于 |
从左到右 |
双目 |
|
|
> |
大于 |
从左到右 |
双目 |
|
|
>= |
大于或等于 |
从左到右 |
双目 |
|
|
instanceof |
确定某对象是否属于指定的类 |
从左到右 |
双目 |
|
|
7 |
== |
等于 |
从左到右 |
双目 |
|
!= |
不等于 |
从左到右 |
双目 |
|
|
8 |
& |
按位与 |
从左到右 |
双目 |
|
9 |
| |
按位或 |
从左到右 |
双目 |
|
10 |
^ |
按位异或 |
从左到右 |
双目 |
|
11 |
&& |
短路与 |
从左到右 |
双目 |
|
12 |
|| |
短路或 |
从左到右 |
双目 |
|
13 |
? : |
条件运算符 |
从右到左 |
三目 |
|
14 |
= |
赋值运算符 |
从右到左 |
双目 |
|
+= |
混合赋值运算符 |
|
|||
-= |
|
||||
*= |
|
||||
/= |
|
||||
%= |
|
||||
&= |
|
||||
|= |
|
||||
^= |
|
||||
<<= |
|
||||
>>= |
|
||||
>>>= |
|
左移位:<<,有符号的移位操作
左移操作时将运算数的二进制码整体左移指定位数,左移之后的空位用0补充
右移位:>>,有符号的移位操作
右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用符号位补充,如果是正数用0补充,负数用1补充。
左移位:<<,有符号的移位操作
左移操作时将运算数的二进制码整体左移指定位数,左移之后的空位用0补充
右移位:>>,有符号的移位操作
右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用符号位补充,如果是正数用0补充,负数用1补充。
解决思路
二进制数的加法
在计算机底层中,数的运算是通过位运算完成的,而位运算的对象是二进制数。下面看一下二进制的加法是怎么一个过程:
十进制数:3 + 5
相当于二进制数:11+101
1.不考虑进位问题,先计算出两个数相加之后各位对应的数字
011 ^ 101 = 110
2.计算出对应位置是否进位 0表示进位 1表示不进位
011 & 101 = 001
3.把计算出的进位结果左移一位,然后与计算的各位数字进行1,2步骤进行计算,直到进位为0
代码如下:
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
if (b == 0)
return a;
else
return aplusb(a^b, (a&b) << 1);
}
}