Java位运算符详解(移位、位与&、或|、非~、异或^)

位运算符

位运算是对操作数以二进制为单位进行的操作和运算,运算结果为整数。位运算符包括:“&”、“|”、“~”、“^”和移位运算符“>>”、“<<”、“>>>”,7个位运算符。

关于二进制有几点需要记的:

  1. 二进制的高位是符号位:0表示正数、1表示负数。
  2. 正数的原码、反码、补码都一样(三码合一)
  3. 负数的反码=它的原码符号位不变,其它位取反(0-->1,1-->0)
  4. 负数的补码=它的反码 + 1,负数的反码=负数的补码 - 1
  5. 0的反码,补码都是0
  6. Java没有无符合数,换而言之,Java中的数都是有符号的
  7. 在计算机运算的时候,都是以补码的方式来运算的
  8. 当我们看结果的时候,要看它的原码

第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 00000011  3的补码=反码=原码

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 00000101  5的补码=反码=原码

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 00000010  2的补码=反码=原码

00000000 00000000 00000000 00000011  3的补码=反码=原码

00000000 00000000 00000000 00000001  2^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

  • 16
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值