一般情况下,编写web应用可能很少接触到位运算场景,但是一旦编写偏底层的框架如hadoop ipc、lucene、数据压缩等位运算必须熟练掌握。
1、按位取反(~)
将每个位的值1变0,0变1。如byte val=1; 那么~val=-2。由于java采用补码,如果需要得到正数的负数就需要将正数按位取反再加1,可以验证-val=~val+1=-1。
2、按位异或(^)
只有位的值不同才等于1否则为0。如0000_0001^0000_0010=0000_0011。小技巧a ^ -1 ^ -1 =a,在zigzag编码中有实际应用。事实上a^b^b=a。证明:假设只考虑1位的情况,令a=0,若b=1则c=a^b=1 , c^b=0=a;
若b=0则c=a^b=0 ,c^b=0=a;
令a=1,若b=1则c=a^b=0 , c^b=1=a;
若b=0则c=a^b=1 ,c^b=1=a;
3、按位与(&)
只有位上值都为1时才等于1否则为0。 0&0=0; 1&1=1; 1&0=0; 0&1=0;
4、按位或(|)
其中有一位数值为1结果等于1否则为0。1 | 0=1;0 | 1=1;0|0=0; 1| 1=1;
5、移位运算
不管是左移、右移、还是无符号右移,对于移动的位数超过32或者64时,都是对32或者64取余后的数进行移位的。右移相当于作除法运算不会改变运算符号,正数右移到最后会变成0,负数右移到最后会变成-1。无符号右移对于负数而言就不同了,因为它始终在最前面补0,那么负数最后会变成正数,移到最后也会变成0。