位与&(真真为真 真假为假 假假为假)
4&6
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0100
结果:4性能
位或|(真真为真 真假为真 假假为假)
4|6
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0110
结果:6spa
位非~(取反码)【注:Java中正数的最高位为0,负数最高位为1,即最高位决定正负符号】
~4
0000 0000 0000 0000 0000 0000 0000 0100
1111 1111 1111 1111 1111 1111 1111 1011变量
解码:先取反码,再补码
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0101
结果:-5数据类型
位异或^(真真为假 真假为真 假假为假)
4^6
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 0110
0000 0000 0000 0000 0000 0000 0000 0010
结果:2方法
有符号右移>>(若正数,高位补0,负数,高位补1)
-4>>2
1111 1111 1111 1111 1111 1111 1111 1100 原码
1111 1111 1111 1111 1111 1111 1111 1111 右移,最左边空出两位按规则负数空位补1
0000 0000 0000 0000 0000 0000 0000 0000 解码
0000 0000 0000 0000 0000 0000 0000 0001 补码(补码即最后一位+1)
结果:-1数据
有符号左移<<(若正数,高位补0,负数,高位补1)
-4<<2
1111 1111 1111 1111 1111 1111 1111 1100 原码
1111 1111 1111 1111 1111 1111 1111 0000 左移,最右边空出两位补0
0000 0000 0000 0000 0000 0000 0000 1111 解码
0000 0000 0000 0000 0000 0000 0001 0000 补码
结果:-16co
无符号右移>>>(不论正负,高位均补0)
-4>>>2
1111 1111 1111 1111 1111 1111 1111 1100 原码
0011 1111 1111 1111 1111 1111 1111 1111 右移(因为高位均补0,故>>>后的结果必定是正数)
结果:1073741823数字
注:位运算
因为数据类型所占字节是有限的,而位移的大小却能够任意大小,因此可能存在位移后超过了该数据类型的表示范围,因而有了这样的规定:return
若是为int数据类型,且位移位数大于32位,则首先把位移位数对32取模,否则位移超过总位数没意义的。因此4>>32与4>>0是等价的。
若是为long类型,且位移位数大于64位,则首先把位移位数对64取模,若没超过64位则不用对位数取模。
若是为byte、char、short,则会首先将他们扩充到32位,而后的规则就按照int类型来处理
使用场景:
1.判断int型变量a是奇数仍是偶数 a&1 = 0 偶数 a&1 = 1 奇数 2.求平均值,好比有两个int类型变量x、y,首先要求x+y的和,再除以2,可是有可能x+y的结果会超过int的最大表示范围,因此位运算就派上用场啦。 (x&y)+((x^y)>>1); 3.对于一个大于0的整数,判断它是否是2的几回方 ((x&(x-1))==0)&&(x!=0); 4.好比有两个int类型变量x、y,要求二者数字交换,位运算的实现方法:性能绝对高效 x ^= y; y ^= x; x ^= y; 5.求绝对值 int abs( int x ) { int y ; y = x >> 31 ; return (x^y)-y ; //or: (x+y)^y } 6.取模运算,采用位运算实现: a % (2^n) 等价于 a & (2^n - 1) 7.乘法运算 采用位运算实现 a * (2^n) 等价于 a << n 8.除法运算转化成位运算 a / (2^n) 等价于 a>> n 9.求相反数 (~x+1) 10.a % 2 等价于 a & 1