Java中的位运算
Java中的位运算主要有以下几种
运算描述
运算符
运算规则
例子
与
&
都是1,结果才为1;其他情况结果为0
1&1=1 1&0=0 0&1=0 0&0=0
或
|
只要有1个1,结果就为1;都是0的时候,结果才为0;
1|1=1 1|0=1 0|1=1 0|0=0
取反
~
1变0,0变1
~0=1 ~1=0
异或
^
相同为0,不同为1
1^1=0 0^0=01 1^0=1 0^1=1
右移
>>
a >> b :所有位右移b位,高位补0
5 >> 1 ===> 0000 0000 0000 0101 >> 1 = 0000 0000 0000 0010 = 2
左移
<<
a << b:所有位左移b位,低位补0
5 << 1 ===> 0000 0000 0000 0101 << 1 = 0000 0000 0000 1010 = 10
无符号右移
>>>
a >>> b :除符号位外,其他位右移b位,高位补0
无符号左移
<<<
a <<< b:除符号位外,其他位左移b位,低位补0
注:位运算时,进行运算的两个数,要转换为二进制,然后从最低位到最高位,一一对应。上面所述的运算规则,均为某位上的两个值的运算规则。例子均是某个位的数值。
要注意 ①位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。 ②位操作符的运算优先级比较低,因为尽量使用括号来确保运算顺序,否则很可能会得到莫明其妙的结果。 **
位运算的技巧或应用
1、乘或除2(或2的倍数4/8/16/32...)的情形,可以考虑使用左移或右移,即<<
或 >>
int a = 9;
int b = a << 1 = 18
int c = a >> 1 = 4
2、判断奇偶 这里利用一个特性:偶数的二进制最低位必为0,奇数的二进制最低位必为1。
//判断i是否为偶数
boolean even = (i & 1) == 0;
//这里有一个小小的常犯的错误,如下代码判断是否为奇数是有问题的:负的奇数运算结果为-1。
boolean odd = (i & 1) == 1;
//正确的判断奇数
boolean odd = ((i & 1) == 1) || ((i & 1) == -1);
解释:1的二进制为0000 0000 0000 0001,对任意的偶数(无论正负),其形式为xxxx xxxx xxxx xxx0(x表示0或1),两数进行与运算,从高位起的前31位必为0,最后一位是1&0=0,所以结果必然是0000 0000 0000 0000。
3、交换两个数的值 利用的特性: ①任意一个数a,a^a=0,且a^0=a,则a^a^a=a ②a^b=b^a
int a = 10, b = 20;
a = a^b;//a = 10^20 = 不关心
b = a^b;//b = 10^20^20 = 10
a = a^b;//a = 10^20^10^20^20 = 20
4、变换符号 变换符号其实就是正数变负数,负数变正数。 其实代码中 a = -a就可以实现,这里只是提供另一种可以使用位运算的方式:a = (~a) + 1
int a = 10, b = -20;
a = (~a) + 1 = (~10) + 1 = -10
b = (~b) + 1 = (~(-20)) + 1 = 20
5、求绝对值 思路①:取符号位,判断其正负 a >> 31:取符号位,0为正数,-1位负数(TODO why)
abs(a) = (a >> 31) == 0 ? a : (~a + 1)
思路②:利用特性:对任意整数a,a^(-1) = ~a;
int i = a >> 31;//a为正数,则i=0;a为负数,则i=-1;
abs(a) = (a^i) - i;
//a为正数,则(a^0) - 0 = a;
//a为负数,则(a^(-1)) + 1 =
TODO 运算示例以及更多应用
参考
Last updated