📄 一句话概括
右移有两种:逻辑右移左边一律补 0,算术右移补的是符号位——正数一样,负数分家。
📝 本节和前面几节的关系
2.4 有了补码,负数正式进入舞台。负数一出现,2.3 讲过的右移就得分成两种。
一、两种右移,只差补什么
逻辑右移:不管这个数是什么,左边一律补 0。 算术右移:左边补的是符号位——正数补 0、负数补 1。 所以对正数,两种移法结果完全一样;只有在负数上,它们才分道扬镳。
二、看 -8 就明白了
-8 的 8 位表示是 1111 1000。 逻辑右移:变成 0111 1100,当成无符号数读是 124。 算术右移:变成 1111 1100,当成有符号数读还是 -4。 而我们想要的是 -8 ÷ 2 = -4——算术右移给对了,逻辑右移彻底给错。
三、为什么要保留两种
因为【移位】在程序里有两类完全不同的用途: 当算术用(有符号数除 2、除 2 的幂)→ 必须用算术右移,保留正负号的含义。 当数据搬家(位运算、哈希、图像处理、协议解析)→ 用逻辑右移,0 就是 0,不掺符号。 两种都有存在的必要——含糊地叫一句【右移】,在负数上就是一个 bug。
四、这条知识怎么用
看到代码里对可能为负的数做右移,先问一句:这里要的是【除 2】还是【搬家】。 要除 2 却写了逻辑右移,结果是错的;要搬家却写了算术右移,会莫名多出一堆 1。 这类 bug 特征很明显:只在负数上出错,正数全对。
五、动手 Demo:逻辑右移与算术右移差在哪
逻辑右移左边一律补 0;算术右移左边补的是符号位。 正数两种移法结果一样,负数才分道扬镳。
for v in (8, -8, -3):
u = v & 0xFF
lg, ar = u >> 1, v >> 1
print("%3d %s 逻辑 %s (%3d) 算术 %s (%3d)"
% (v, format(u, "08b"), format(lg, "08b"), lg,
format(ar & 0xFF, "08b"), ar))
实跑输出:
--------------------------------------------------------------------
逻辑右移与算术右移差在哪
--------------------------------------------------------------------
**逻辑右移:左边一律补 0,不管这个数是什么。**
**算术右移:左边补的是符号位——正数补 0,负数补 1。**
正数两种移法结果一样,**负数才分道扬镳**。
值 8 位表示 逻辑右移 -> 当成无符号读 算术右移 -> 当成有符号读
----------------------------------------------------------------------------------
8 00001000 00000100 4 00000100 4
-8 11111000 01111100 124 11111100 -4
-3 11111101 01111110 126 11111110 -2
看 -8 那一行:
逻辑右移 -> 0111 1100,当成无符号数是 124
算术右移 -> 1111 1100,当成有符号数还是 -4
**要保留正负号的含义,就必须用算术右移;把它当纯数据搬家,就用逻辑右移。**
教材特意点出这一条,是因为它直接决定【负数除 2 对不对】:
-8 ÷ 2 = -4,算术右移给的就是 -4;逻辑右移给的是 124——完全错了。
-8 逻辑右移得 0111 1100(当无符号读是 124),算术右移得 1111 1100(有符号读是 -4)。 要保留正负号的含义,就必须用算术右移。
30 秒实验
- 手算 -16 的算术右移一位,再用无符号读法算一遍逻辑右移,两个答案差多少?
- 在代码里对一个可能为负的变量做右移,看它给的是除法还是搬家。
常见误区
- 以为【右移就是除 2】。对负数不成立——要看你用的是哪种右移。
- 以为两种右移只是写法区别。在负数上它们是两种完全不同的运算。
自测三问(点开对答案)
1. 逻辑右移和算术右移的区别是什么? —— 逻辑右移左边一律补 0;算术右移补的是符号位。 2. 为什么负数上必须区分它们? —— 负数符号位为 1,逻辑右移会把负数变成一个大正数,除 2 的含义就丢了。 3. 什么时候该用逻辑右移? —— 把数据当纯粹的位来处理时(位运算、哈希、协议解析),此时 0 就是 0。- ☐ 下一节(2.6 掌握逻辑运算的窍门)
相关笔记
- 移位运算与乘除运算的关系 — 移位的基础
- 便于计算机处理的【2的补码】 — 负数从哪儿来
- 掌握逻辑运算的窍门 — 位级操作的另一半工具箱
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引