位运算是二进制数的各种操作的统称, 本篇是移位操作.
- 计算机中的位运算操作都是以其补码参与运算
- 正数的三码(
原码
/反码
/补码
)一致 - 负数的三码,
反码
是原码
除符号位取反,补码
是反码
加一
下面我们直接上例子分别说说移位操作需要注意的点.
为了书写方便, 我们使用
byte
来做演示. 实际运算会将byte
类型转换为int
类型计算
补位约定
- 正数右移,高位用
0
补, - 负数右移,高位用
1
补, - 当负数使用无符号右移时,高位用
0
进行补位(自然由负数变成了正数) - 左移不管正数负数低位都是补
0
正常情况
移位操作分三种
- 左移
<<
- 右移
>>
- 无符号右移
>>>
正数移位
正数左右移位都比较简单, 这里就各给一个例子, 大家看看就好
(1) 3 >> 1
0000 0011 原码/补码/反码
0000 0001 右移一位
移位后的结果也是正数, 那么其原码就是其自身
3 >> 1 = 2
(2) 1 << 7
转换为int
计算
0000 ... 0000 0000 0001 原码/补码/反码 (中间省略16个0)
0000 ... 0000 1000 0000 左移七位
答案就是 128
让我们换一种写法:
(byte) (1 << 7)
前面过程与上面一致,到输出时有所不同:
转换为byte
输出, 截取低八位得到
1000 0000
这是个负数呀, 继续转
1111 1111 取反
1000 0000 加一
这是多少? -0
? 不是, 是 -128
(byte
范围的最小负数)
- 这里之所以写出来
转换为int
并且写满了32
位, 是因为涉及到了这种临界点必须写出来不然结果就看不懂了, 上面也是会转的, 只是写不写出来结果都一样 -
int
转byte
分三步- 拿到补码
- 截掉前面三个字节
- 当补码处理, 取原码
1 >> 9
是多少呢?
负数右移
-3 >> 1
原码 1000 0011
反码 1111 1100 (取反时符号位不动)
补码 1111 1101
右移一位 1111 1110 (这里得到的是补码)
根据补码取其原码,
取反 1000 0001
加一 1000 0010
所以
-3 >> 1 = -2
你猜猜
-3 >> 33
是多少? (那个圈~~)
因为 33 % 32 = 1
, 所以
-3 >> 33 = -3 >> 1 = -2
无符号右移
就是连带符号位一起移动~
-1 >>> 1
1000 ... 0001 原码
1111 ... 1110 反码
1111 ... 1111 补码
0111 ... 1111 无符号右移一位
结果就是 2147483647
相信你应该看出来了, 正数的右移与无符号右移是一样一样的, 都是高位补0
.
其实移位操作只要细心点加多动手画画基本不会错.
网友评论