逻辑右移、算术右移、循环右移的区别
The difference between logical shift right, arithmetic shift right, and rotate right
我一直在阅读经典的 Hacker's delight,但我无法理解逻辑右移、算术右移和循环右移之间的区别。如果怀疑看起来太简单,请原谅。
差异在最右边的列中得到了很好的解释。
- 逻辑移位将数字视为一堆位,并以零移位。这是 C 中的
>>
运算符。
算术移位将数字视为有符号整数(2s补码),"retains"最高位,如果最高位为0则移零,如果是则移1一。如果被移位的数字是负数,C 的右移运算符具有实现定义的行为。
例如,二进制数 11100101
(-27,十进制,假设 2s 补码),当使用逻辑移位右移 3 位时,变为 00011100
(十进制 28)。这显然令人困惑。使用算术移位,符号位将被保留,结果将变为 11111100
(十进制 -4,大约适合 -27 / 8)。
旋转都不做,因为最上面的位被最下面的位替换了。 C 没有运算符来进行旋转。
首先要记住机器字的大小是固定的。说 4,你的输入是:
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
然后将所有内容向左推一个位置得到:
+---+---+---+---+
| b | c | d | X |
+---+---+---+---+
问X应该放什么?
- 用 shift 放 0
- 用旋转放
a
现在将所有内容向右推一个位置给出:
+---+---+---+---+
| X | a | b | c |
+---+---+---+---+
问X应该放什么?
- 用 逻辑移位 放 0
- 使用 算术移位 将
a
- 用旋转放
d
大致。
逻辑移位对应(左移)乘以2,(右移)整数除以2。
算术移位 与有符号数的 2 补码表示有关。在这种表示中,符号是最左边的位,然后算术移位保留符号(这称为符号扩展)。
旋转没有普通的数学意义,即使在计算机中也几乎是一个过时的运算。
逻辑右移表示将位右移,MSB(最高有效位)变为0。
示例:数字 1 0 1 1 0 1 0 1 的逻辑右移是 0 1 0 1 1 0 1 0.
算术右移表示将位右移,MSB(最高有效位)与原数相同
例子:数 1 0 1 1 0 1 0 1 的算术右移是 1 1 0 1 1 0 1 0。
我一直在阅读经典的 Hacker's delight,但我无法理解逻辑右移、算术右移和循环右移之间的区别。如果怀疑看起来太简单,请原谅。
差异在最右边的列中得到了很好的解释。
- 逻辑移位将数字视为一堆位,并以零移位。这是 C 中的
>>
运算符。 算术移位将数字视为有符号整数(2s补码),"retains"最高位,如果最高位为0则移零,如果是则移1一。如果被移位的数字是负数,C 的右移运算符具有实现定义的行为。
例如,二进制数11100101
(-27,十进制,假设 2s 补码),当使用逻辑移位右移 3 位时,变为00011100
(十进制 28)。这显然令人困惑。使用算术移位,符号位将被保留,结果将变为11111100
(十进制 -4,大约适合 -27 / 8)。旋转都不做,因为最上面的位被最下面的位替换了。 C 没有运算符来进行旋转。
首先要记住机器字的大小是固定的。说 4,你的输入是:
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
然后将所有内容向左推一个位置得到:
+---+---+---+---+
| b | c | d | X |
+---+---+---+---+
问X应该放什么?
- 用 shift 放 0
- 用旋转放
a
现在将所有内容向右推一个位置给出:
+---+---+---+---+
| X | a | b | c |
+---+---+---+---+
问X应该放什么?
- 用 逻辑移位 放 0
- 使用 算术移位 将
a
- 用旋转放
d
大致。
逻辑移位对应(左移)乘以2,(右移)整数除以2。
算术移位 与有符号数的 2 补码表示有关。在这种表示中,符号是最左边的位,然后算术移位保留符号(这称为符号扩展)。
旋转没有普通的数学意义,即使在计算机中也几乎是一个过时的运算。
逻辑右移表示将位右移,MSB(最高有效位)变为0。
示例:数字 1 0 1 1 0 1 0 1 的逻辑右移是 0 1 0 1 1 0 1 0.
算术右移表示将位右移,MSB(最高有效位)与原数相同
例子:数 1 0 1 1 0 1 0 1 的算术右移是 1 1 0 1 1 0 1 0。