Java基础-源码分析-位运算的妙用
2021-01-01 本文已影响0人
HughJin
注意:位运算只用于整数,并且如果超过范围所得值为0。比如8>>4,并不是0.5而是0
&:与,且
性质:两个数字的个位都是1时,结果是1,否则为0
用途:
- 清零:任意整数和整数0做与运算,所有位都是0,得出的结果是0
- 取出指定位:任意位和位1做与运算,结果是不变,例如x=10101110取出低4位,只需要和y=00001111做与运算,就可以得出z=00001110
- 判断奇偶:二进制中,能表示基数,那么二进制的最后一位一定是1
错误判断方法:通过a%2==1
来判断。(原因:负奇数对2取余的结果为-1)
正确判断方法:
(1) 通过a%2!=0
来判断。
(2) 通过(a&1)==1
为奇数来判断。
(3) 通过(a&1)==0
为偶数来判断。 - 将最后一位变为0:num & (num - 1)会将num的二进制表示的最后一位的1变成0
- 判断一个数是不是2的幂:(num & (num - 1)) == 0,如果一个数是2的次幂,这个数的二进制表示中,一定只有一个位是1,这个数与它减1的数做&运算的结果一定是0
- a & b的结果小于等于min(a,b)
- a & b,当b是(2的次幂)-1时,与运算的值是分散最广的
^:异或;
性质:两个位相同为0,不同为1;x ^ x = 0 , x ^ 0 = x;
遵循交换律、结合律
用途:
- 交换两个数
x ^= y;
y ^= x;
x ^= y;
>>:右移
性质:右移运算符(>>)就是向右移动指定的位数,左边补上0.相当于乘以2
-
带符号右移(>>)的运算规则与无符号右移(>>>)的运算规则差别就在于:无符号右移(>>>)在二进制串移动之后,空位由0来补充,与符号位是0还是1毫无关系.
-
右移(>>) 32 位不进行操作,右移(>>)40位相当于右移(>>)8位(40%32=8)。如果是 long 类型,则相应的操作位数会变大,变成64 位,所以 long 类型 右移(>>) 64 位无变化,右移(>>) 66 位相当于右移(>>) (66%64 = 2)位
代码测试:
System.out.println(5>>2);// 1 说明:与5/2/2结果相同
System.out.println(5>>>2);// 1 说明:与5/2/2结果相同
System.out.println(-5>>2);// -2 说明:符号位不右移
System.out.println(-5>>>2);// 1073741822 说明:符号位会右移
System.out.println(-5 >> 31);// -1 说明:符号位不右移
System.out.println(-5 >>> 31);// 1 说明:符号位会右移
System.out.println(-5 >> 32);// -5 说明:右移(>>) 32 位不进行操作
System.out.println(-5 >> 34);// -2 说明:右移(>>) 34 位相当于右移(>>)2位 与5/2/2结果相同
- 左移(<<)运算符就是向左移动指定的位数,右边补上0.相当于乘以2
位运算符综合运用
-
求平均值,比如有两个int类型变量x、y,首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围,所以位运算就派上用场啦。
(x&y)+((x^y)>>1);
-
求绝对值
int abs( int x )
{
int y ;
y = x >> 31 ;
return (x^y)-y ; //or: (x+y)^y
}
- 取模运算,采用位运算实现:
a % (2^n)
等价于a & (2^n - 1)