位运算符
位运算是对操作数以二进制为单位进行的操作和运算,运算结果为整数。位运算符包括:“&”、“|”、“~”、“^”和移位运算符“>>”、“<<”、“>>>”,7个位运算符。
关于二进制有几点需要记的:
二进制的高位是符号位:0表示正数、1表示负数。正数的原码、反码、补码都一样(三码合一)负数的反码=它的原码符号位不变,其它位取反(0-->1,1-->0)负数的补码=它的反码 + 1,负数的反码=负数的补码 - 10的反码,补码都是0Java没有无符合数,换而言之,Java中的数都是有符号的在计算机运算的时候,都是以补码的方式来运算的当我们看结果的时候,要看它的原码
第7点和第8点可以总结为:运算看补码,结果看原码
注意:二进制向上借位是以2为单位借的
下面详细介绍每个位运算符。
一、&(按位与)
按位与的运算符用符号“&”表示,按位与参与运算的数字,低位对齐,高位不足的补0,当对应的二进制位都为1时,计算结果才为1,否则都为,由此可看出,任何数与0按位与运算,其结果都为0。
使用规律:全为1,结果为1,否则都为0
例:9&3
推导:
9和3默认是int,int是4字节,按1个字节等于8位int就是32位。
因为两个数都是正数,原码、反码、补码都一样。
运算看补码,结果看原码
9的补码:00000000 00000000 00000000 00001001
3的补码:00000000 00000000 00000000 00000011
&的结果:00000000 00000000 00000000 00000001
结果是补码,因为符号位是0为正数,所以原码=反码=补码,推导出的结果为1
二、|(按位或)
按位或的运算符用符号“|”表示,按位或参与运算的数字,低位对齐,高位不足的补0。只要对应的二进制位有一个为1,那么结果就为1,否则都为0。
使用规律:有一个为1,结果就为1,否则都为0
例:-9|3
推导:
3的原码=反码=补码
因为-9是负数,所以二进制高位符号位是1,由此得到原码,通过原码符号位不变,其他位取反得到反码,再由负数的反码+1得到负数的补码进行运算
通过按位或运算得到补码,再由补码得到反码得到原码,推导出结果
10000000 00000000 00000000 00001001 -9的原码
11111111 11111111 11111111 11110110 -9的反码
11111111 11111111 11111111 11110111-9的补码
00000000 00000000 00000000 000000113的补码=反码=原码
11111111 11111111 11111111 11110111-9|3的补码结果
11111111 11111111 11111111 11110110 由负数的补码-1得到-9|3运算结果的反码
10000000 00000000 00000000 00001001 由符号位不变,其它位取反得到原码
由原码推导出 -9|3 位运算后的结果为 -9
三、~(按位取反)
按位取反的运算符用符号“~”表示,按位取反是只对一个操作数进行运算,将操作数二进制中的1改为0,0改为1。
使用规律:是1为0,是0为1
例:~5
00000000 00000000 00000000 000001015的补码=反码=原码
11111111 11111111 11111111 11111010~5运算过后的补码
11111111 11111111 11111111 11111001 ~5的反码
高位符号位为1,是负数,补码-1=反码,0-1需向上(左)借位,则2-1为1,上(左)的1借走了,则上(左)原来的1变为为0
10000000 00000000 00000000 00000110 运算过后的原码
由原码推导出 ~5 位运算后的结果为 -6
四、^(按位异或)
按位异或的运算符用符号“^”表示,按位异或参与运算的数字,低位对齐,高位不足补0,对应的二进制位有一个为0,一个为1,结果为1,否则都为0。
使用规律:两者相等为0,不等为1
例:2^3
00000000 00000000 00000000 000000102的补码=反码=原码
00000000 00000000 00000000 000000113的补码=反码=原码
00000000 00000000 00000000 000000012^3运算过后的补码=反码=原码
由原码推导出 2^3 位运算后的结果为 1
五、>>(算术右移)
算术右移的运算符用符号“>>”表示,算术右移按二进制形式把所有的数向右移动对应的位数,低位移出(舍弃),正数的高位的空位补0,负数的高位的空位补1。
使用规律:低位溢出,符号位不变,并用符号位补溢出的高位
或
右移n位就除以n次2或是除以2的n次幂
例:1>>2
00000000 00000000 00000000 00000001移位前 1正数补码=反码=原码
00000000 00000000 00000000 00000000移位后
1向右移两位 01是低位溢出直接舍去,高位符号是0,溢出的两位用0补充
由原码推导出 1>>2 运算后的结果为0
1/2/2 == 0 //在java中int 1/2/2不是等于0.25,而是等于0
六、<<(算术左移)
算术左移的运算符用符号“<<”表示,算术左移按二进制形式把所有的数字向左移动对应的位数,符号不变,高位移除(舍弃),低位补零。
使用规律:符号位不变,低位补0
或
左移n位就乘以n次2或是乘以2的n次幂
例:1<<2
00000000 00000000 00000000 00000001移位前 1正数补码=反码=原码
00000000 00000000 00000000 00000100移位后
1向左移两位 高位溢出舍去,保证高位符号位不变,低位补两个00补充
由原码推导出 1<<2 运算后的结果为 4
1*2*2 == 4
七、>>>(无符号右移)
无符号右移运算符用符号“>>>”表示,无符号右移按二进制形式把所有的数字向右移动相对应的位数,低位移出(舍弃),高位的空位补零(无论正数负数都补零)。
使用规律:低位溢出,高位补 0
例:-10 >>> 3
10000000 00000000 00000000 00001010 -10的原码
11111111 11111111 11111111 11110101 -10的反码
11111111 11111111 11111111 11110110-10的补码
00011111111 11111111 11111111 11110移位后
低位110溢出舍去,高位补三个0,符号位是正数,所以补码=反码=原码
由原码推导出 -10>>>3 运算后的结果为536870910
注意:位运算中没有 <<< 符号
总结
&(按位与):全为1,结果为1,否则都为0
|(按位或):有一个为1,结果就为1,否则都为0
~(按位取反):是1为0,是0为1
^(按位异或):两者相等为0,不等为1
>>(算术右移):低位溢出,符号位不变,并用符号位补溢出的高位
<<(算术左移):符号位不变,低位补0
>>>(无符号右移):低位溢出,高位补 0