一篇文章弄懂左移、右移位运算(Java)

对于左移,右移,大多数人都知道下面两点

  • 左移将原数乘以2
  • 右移将原数除以2

下面先来展示上面两点

原数: 100
整型是4字节32位,将100以整型的二进制表示
二进制: 00000000 00000000 00000000 01100100


100 >> 2
二进制: 00000000 00000000 00000000 00011001 | 00
解释: | 后面被剔除,前面缺少的两个补0
结果: 25
右移两位相当于除以2,再除以2,结果为25


100 << 2
二进制: 00 | 00000000 00000000 00000001 100100 00
解释: | 前面被剔除,后面缺少的两个补0
结果: 400
左移两位相当于乘以2,再乘以2,结果为400

测试

一篇文章弄懂左移、右移位运算(Java)_第1张图片
在这里插入图片描述


换个例子

原数: 75
二进制: 00000000 00000000 00000000 01001011


75 << 25
二进制: 00000000 00000000 00000000 0 | 10010110 00000000 00000000 00000000
解释: | 前面被剔除,后面缺少补0
结果: -1778384896
——这里应当要知道的一点,最高位是符号位,75的最高位为0表示为正数,左移9位后最高位位1表示为负数


原数: -10
二进制: 11111111 11111111 11111111 11110110
注意:负数的二进制位正数的反码+1
原数: 10
二进制: 00000000 00000000 00000000 00001010
反码: 11111111 11111111 11111111 11110101
+1得负数的二进制 11111111 11111111 11111111 11110110


-10 >> 1
二进制: 01111111 11111111 11111111 11111011 | 0

该这样吗?答案是错的,负数右移,高位应该补1
正确的二进制: 11111111 11111111 11111111 11111011 | 0
解释: | 后面被剔除,前面缺少的补1
负数的反码: 00000000 00000000 00000000 00000100
反码+1得正数: 00000000 00000000 00000000 00000101
正数得值为: 5
所以负数得值为: -5


测试
一篇文章弄懂左移、右移位运算(Java)_第2张图片
一篇文章弄懂左移、右移位运算(Java)_第3张图片
这里我们知道了

  • 左移需要考虑符号问题
  • 负数右移最高位补1

思考一个问题?

整型为4个字节32位,那么当我们右移32位会发生什么?35位呢?


原数(整型最大值): 2147483647
二进制: 01111111 11111111 11111111 11111111


右移32位会是这样吗?
二进制: 00000000 00000000 00000000 00000000 | 01111111 11111111 11111111 11111111
在这里插入图片描述
在这里插入图片描述
结果竟然没有变!
这是因为位移是一个取模得过程
当我们右移4位:4 % 32 = 4
当我们右移32位:32 % 32 = 0 也就是不动
那么当右移33位,那不就是右移1位吗!
在这里插入图片描述
在这里插入图片描述
答案确实如此!


最后我们来看一下无符号右移(没有无符号左移)

无符号右移在右移时,高位补0,也就是不会管你是不是负数
-10 >>> 1
二进制: 01111111 11111111 11111111 11111011 | 0

该这样吗?答案是对的,负数无符号右移,高位同样补0

无符号右移1位后最高位的1变为了0,负数变为了正数
一篇文章弄懂左移、右移位运算(Java)_第4张图片
在这里插入图片描述


总结——

  • 负数有符号右移高位补1
  • 负数无符号右移高位补0
  • 位移是一个取余得过程
  • 无符号右移无论正负高位添0

你可能感兴趣的:(笔记)