示例详解Java位运算符 >>>、^、&、<<、>>

Java基础中的位运算符逐个进行说明:
1、^(异或运算)

2^3 = 1
先将数字转换为二进制
2 = 0010
3 = 0011
对 0010 和 0011 逐个数字比较,如果数字相同则计为 0,如果不相同则计为 1,故得出结果为 0001
将 0001 转换为十进制后为 1

2、&(与运算)
如果 A&B 左右有一个 boolean 则结果返回 boolean,否则当AB都是 int 则进行位运算

2&3 = 2
先将数字转换为二进制
2 = 0010
3 = 0011
对 0010 和 0011 逐个数字比较,如果数字有一个为 0 则为零,否则为 1,故得出结果为 0010
将 0010 转换为十进制后为 2

3、<<(向左位移)
将数字先转换为二进制,然后向左移动N位,右边补0

2 << 3 = 16
先将数字转换为二进制
2 = 0010
然后 0010 向左移动3位后右边补 0 结果为 10000(0010 中的第一个1前面只有2个0所以整体左移3位需要在右边补1个0,得10000)
将 10000 转换为十进制后为 16

4、>>(向右位移)
想将数字转换为二进制,然后向右移动N位

2 >> 3 = 0
先将数字转换为二进制
2 = 0010
然后 0010 整体向右移动3位后结果为 0000 (0010 中只有一个1,向右移动3位后就移出了,故为 0000)
将 0000 转换为十进制后为 0

5、>>>(无符号向右位移)
将数字转换为二进制后,然后向右移动N位
以 16 >>> 2 和 -16 >>> 2 为例说明

16的二进制值为 10000
Java中 int 类型是4个字节的也就是32位的,所以实际上16的二进制表示实际为 0000 0000 0000 0000 0000 0000 0001 0000,因为正数高位都是0,所以前面的所有0都可以直接忽略掉了,所以简写为 10000,向右位移 2 得 00100,100 转换为十进制为 4
所以:对正数来说 >> 和 >>> 结果是一样的。并且正数的三码(源码、反码、补码)相同。左移则表示放大2的N次方,右移表示缩小2的N次方。

对于负数来说,就不一样了(在计算机中,负数以其正值的补码形式表达),所以负数是在其正数二进制后,先反码再补码的结果。
(也就是:正数(十进制)》二进制(源码)》源码的反码》反码加1得到补码)。
所以(源码)0000 0000 0000 0000 0000 0000 0001 0000 》(源码的反码)1111 1111 1111 1111 1111 1111 1110 1111》(补码)1111 1111 1111 1111 1111 1111 1111 0000

所以 -16 >>> 2 即是 1111 1111 1111 1111 1111 1111 1111 0000 右移2位(高位不考虑符号以0补齐)得 0011 1111 1111 1111 1111 1111 1111 1100 然后转换为 10进制的结果为 1073741820
所以:无符号位移,按步骤转换后得到的二进制直接转换为十进制即为结果。

然后 -16 >> 2 即是 1111 1111 1111 1111 1111 1111 1111 0000 右移2位(高位考虑符号负数以1补齐)得 1111 1111 1111 1111 1111 1111 1111 1100 然后接下来与无符号就不同了,有符号位移后的二进制,需要进行还原,还原后的结果才是最终位移后的结果。
还原步骤为:位移后结果》减一(去补码)》再反码》得到源码》转换十进制得最终结果。
所以 1111 1111 1111 1111 1111 1111 1111 1100 减一1后取反(或按位取反再加上1这样用加法比较直观)0000 0000 0000 0000 0000 0000 0000 0100 然后 100 转换为十进制为 4,最后保留符号(负数) ,得 -4

总结:
1、把 >>> 弄明白了,上面的也就都明白了。
2、为什么没有 <<< 呢?因为无符号左移和有符号左移都是始终在右边补0,这两者没有区别,故 Java 中不存在 <<< 。


(END)

发布了378 篇原创文章 · 获赞 1419 · 访问量 632万+

猜你喜欢

转载自blog.csdn.net/catoop/article/details/100716948