位运算是把数字用二进制形式表示之后,对每位上0或1的运算。
1.位运算:
-
位运算只有六种:
~
(非)、&
(与)、|
(或)、^
(异或)、<<
(左移)和>>
(右移)。 -
非运算对整数的二进制按位取反,0取反得1,1取反得0。下面对8位整数进行非运算:
~10001010=01110101,~00001010=11110101 -
与、或、异或的运算:
与(&) | 0&0=0 | 1&0=0 | 0&1=0 | 1&1=1 |
---|---|---|---|---|
或(|) | 0|0=0 | 1|0=1 | 0|1=1 | 1|0=1 |
异或(^) | 0^0=0 | 1^0=1 | 0^1=1 | 1^1=0 |
- 位运算基础操作:
2.<<
、>>
与>>>
:
-
左移运算符m
<<
n表示把m左移n位。如果左移n位,那么最左边的n位将被丢弃,同时在最右边补上n个0。具体示例如下:00001010<<2=00101000,10001010<<3=01010000 -
右移运算符m
>>
n表示把m右移n位。如果右移n位,则最右边的n位将被丢弃。但右移时处理最左边位的情形比较复杂。下面是对8位有符号数值(Java中的byte型整数)进行右移的例子:00001010>>2=00000010,10001010>>3=11110001 -
Java中增加了一种无符号右移位操作符“
>>>
”。无论是对正数还是负数进行无符号右移操作,都将在最左边插入0。下面是对Java中byte型整数进行无符号右移操作的例子:00001010>>>2=0000001010001010>>>3=00010001
3.位运算的常见用法:
-
1.乘2,除以2,乘2加1
a2=a<<1正负数通用;
a/2=a>>2正负数通用;
a2+1=a<<2|1,原因是左移后最后一位必为0,按位或运算符和1运算可与把末位置0置为1
-
2.异或:交换两个数
int a=2,b=1;
a=a^b;
b=a^b;
a=a^b;
得到a=1,b=2
-
3.判断奇偶
x&1=1为奇数,x&1=0为偶数 原因:奇数最后一位是1,&1后为1,偶数最后一位为0,&1后为0
-
4.求绝对值
对于负数,可以通过变换符号的操作得到绝对值,正数直接返回即可。
先判断正负:
public int abs(int a){
int i=a>>31;//得到符号位,0为正数,-1为负数
return i==0?a:(~a+1);//符号位为0直接返回,否则返回~a+1
}
或者,n>>31取得n的符号,若n为正数,n>>31等于0,若n为负数,n>>31等于-1,若n为正数n^0-0数不变,若n为负数n^-1,需要计算n和-1的补码,异或后再取补码,结果n变号并且绝对值减1,再减去-1就是绝对值
public int abs(int a){
return (a^(a>>31))-(a>>31);
}