‘&’位运算-与
运算规则:运算时均把运算数转换为二进制再做比较,0&0=0、0&1=0、1&0=0、1&1=1,即当相同的位上均为1时结果为1
例: 8 & 9 ——> 1000 & 1001 = 1000(二进制) ——>8(十进制)
扩展 : h & (length-1)操作 等价于 hash % length操作,&性能比%的性能更优,此例在hashMap中用到
‘|’ 位运算-或
运算规则:运算时均把运算数转换为二进制再做比较,0|0=0、0|1=1、1|0=1、1|1=1,即当相同的位有1时结果为1
例: 8 | 9 ——> 1000 & 1001 = 1001(二进制) ——>9(十进制)
‘^’ -异或
运算规则:运算时均把运算数转换为二进制再做比较,0^0=0、0^1=1、1^0=1、1^1=0,即当相同的位x相反时结果为1
例:8 ^ 9 ——> 1000 ^ 1001 = 0001(二进制) ——>1(十进制)
‘~’ -取反
运算规则:运算时均把运算数转换为二进制再做比较,将0–>1、1–>0;
例:9转换为二进制为1001,Java 中的数据类型默认为int,int数据类型的长度为8位,32字节,所以取反后为11111111111111111111111111110110
注意:取反的结果不是反码。
这里顺便复习一下补码,原码,反码。
在Java中,所有数据的表示方式都是以补码形式来表示,因为用补码方便运算 详细请看这篇文章
因此我们在输入System.out.println(Integer.toBinaryString(-9));
的时候得到的是-9的补码;
因为正数的反码,补码,原码都一样
所以我们只讨论负数
就-9吧——>1001(b)
原码:1000,0000,0000,0000,0000,0000,0000,1001 (逗号为了方便阅读)
反码:1111,1111,1111,1111,1111,1111,1111,0110(第一位不变其他取反)
补码:1111,1111,1111,1111,1111,1111,1111,0111(反码基础上最后一位加一 )
‘<<’ -左移
原理:将a的二进制数左移2位,右补0,高位舍弃
例: 8<<2=32 将8的二进制(1000)数左移两位,右边补零(10,0000)->32;
从结果上分析其实就是8*2^2;左移几位就是几次方。但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。
‘>>’ -右移
原理:将a的二进制数右移2位,右边溢出舍弃,左边空出的位用0或者1填补。正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;
例: 8>>2=2 将8的二进制(1000)数右移两位,右边补零(0010)->2;
从结果上分析其实就是8/2^2;右移几位就是几次方。
注:移位运算操作比乘除要快,有关2次幂的乘除用移位运算