一次性搞清楚Java中右移运算符和左移运算符

今天在ArrayList源码的时候看到扩容机制中的右移操作
一次性搞清楚Java中右移运算符和左移运算符
一时没反应过来到底是扩容了多少,痛定思痛的决定好好研究下java中的左移右移操作。
提示:由于下文涉及到原码,补码,反码等相关知识,有疑问的同学可以移步https://www.cnblogs.com/goahead–linux/p/10904701.html了解一下,个人觉得这篇博客解释的很透彻

左移 <<

      由于不需要考虑符号位的变化,对左移来说左移时只需要在右边加0就可以,逻辑左移和算术左移都是一样的,在Java中左移操作符只有<<,所以相对比较简单。
      比如2<<3用二进制表示就是10→10000也就是16,对于二进制的数值来说左移n位等于原来的数值乘以2的n次方,2<<3就是2*23=16,这样计算起来会方便一点。

右移

      由于右移时需要考虑符号位的变化,所以Java中的右移有算术右移>>和逻辑右移>>>

算术右移 >>

      算术右移就是考虑符号位的右移,右移之后的空位用符号位来补充,我们知道在二进制中符号位用0来表示正数,1来表示负数,所以如果是负数右移就往左边补1,正数右移就往左边补0。
      拿-4来举例,-4>>1,
-4的原码
10000000 00000000 00000000 00000100
-4的补码
11111111111111111111111111111100
右移1位,左边补1
11111111111111111111111111111110 [0]
重新取补码
10000000 00000000 00000000 00000010
结果为-2
如果是4呢,4>>1,
4的原码,补码
00000000000000000000000000000100
右移1位,左边补0
00000000000000000000000000000010 [0]
结果为2

逻辑右移 >>>

      逻辑右移就是不考虑符号位的右移,也就是不管正数还是负数,右移时都往左边补0。
      用-1来举例,-1>>>1
-1的原码
10000000 00000000 00000000 00000001
-1的补码
11111111111111111111111111111111
右移1位,左边补0
01111111111111111111111111111111 [1]
符号位为0,所以补码相同,结果为231-1

      如果是1>>>1呢
1的原码,补码
00000000000000000000000000000001
右移1位
00000000000000000000000000000000 [1]
结果为0
6>>>2
6的原码,补码
00000000 00000000 00000000 00000110
右移2位
00000000 00000000 00000000 00000001 [10]
结果为1