通过移位了解正确的移位运算符

时间:2019-03-17 04:19:21

标签: c++ bit-shift

我很难理解正确的换档符。我了解左移。说不行

int n = 11; which is 1011

现在,如果我们左移n << 1 结果是

int a = n << 1 ; so a = 10110; (simply add a 0 to the end)

这很有意义

现在右移是我遇到的困难

int a = n >> 1

我认为答案是01011(在前面加上0),它将再次为1011,但改为101。我的问题是我们如何松开最后一位数字。

更新: 我的理由可能是假设int为8位,在这种情况下,我们将 int8 n = 1011 =>这是00001011 因此,当我们右移1时,它会超过8位int乘以1,因此最后一位被丢弃,它变为 0000101?这种理解正确吗?

5 个答案:

答案 0 :(得分:7)

似乎您对轮班工作方式有误解。

移位不会添加零的左边或右边。您不能只添加数字,只有那么多的位。让我们以您的数字,十进制数字11为例。

  

int n = 11;是1011

这是事实,但只有一半。看,数字在您的CPU中具有固定大小。对于整数,多数民众赞成在32位,但是为了简化起见,我们假设8位数字。您的11看起来像这样:

+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|1|1|
+-+-+-+-+-+-+-+-+

它有8位。总是。现在让我们左移1:

 +-+-+-+-+-+-+-+-+
0|0|0|0|1|0|1|1| |
 +-+-+-+-+-+-+-+-+

移位后,第一位“移出”。没有空间来存储该位。另外,最后一位是“空”,我们不能存储“空”。只有一或零。相反,我们“移入”零。这样你就结束了

+-+-+-+-+-+-+-+-+
|0|0|0|1|0|1|1|0|
+-+-+-+-+-+-+-+-+

右移则相反。我们从11开始:

+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|1|1|
+-+-+-+-+-+-+-+-+

并向右移动1:

+-+-+-+-+-+-+-+-+
| |0|0|0|0|1|0|1|1
+-+-+-+-+-+-+-+-+

同样,每一位都右移1。在左侧,有一个空位,就像以前一样,它变为零。在右边,一个被转移了,没有空间存储它了。它只是迷路了。我们的最终号码是:

+-+-+-+-+-+-+-+-+
|0|0|0|0|0|1|0|1|
+-+-+-+-+-+-+-+-+

无符号数字为真,也称为逻辑右移。在二进制补码系统中,对于有符号数,它使用所谓的算术右移,它不是以零位进行移位,而是以符号位进行移位。即如果数字为负,则最高有效位为1,则移位为1,否则为零。

答案 1 :(得分:3)

右移后

1011将是101。从1011最右边被删除

111110101右移3时得到111110,删除了加粗的位111110 101

答案 2 :(得分:3)

有几种查看方法。

首先,整数数值类型(在C,C ++,Java,C#中)具有固定的位数。所以实际上是11(假设可读性很少见的8位整数):

 00001101 (8 digits)

左移一位

000011010 (9 digits?)

但是由于我们的整数只能管理8位,因此最左边的位会下降。

00011010 (8 digits)

32位整数也会发生同样的情况:最左边的位会下降。

向右移位时也会发生同样的情况:右侧的位会掉落。 如果原始文件是:

00011010 (8 digits)

然后在左侧添加一个位将创建9位值,该值不受支持。相反,添加的零将所有位向右推一位,最右边的位下降,结果为

00001101 (8 digits)

另一种查看方式是乘法和除法。用十进制数表示,当我们乘以10时,在右边加零。左移就像乘法,但用于二进制。当我们除以10时,则删除最右边的数字并将其放在小数部分。正二进制和右移是相同的,我们只是损失了分数。

请注意,对于负数,C ++中的情况更为复杂。例如,left shifting a negative is undefined

答案 3 :(得分:1)

假设我们有一个数字(我们将其简化为Bundle),并且想将其左移,它看起来像这样:

00010000

我们取了一个数字,并将00010000 << 1 = 00100000 列中每一列的值放在其左侧(因为1是我们放在位移的另一个操作数上的数字)。

到目前为止和我在一起吗?好。

现在,右移有什么作用?好吧,它的作用与此相反。它将x列中每列的值放在其 right 处。例如:

1

更多高级示例:

00010000 >> 1 = 00001000

注意:移位将切断在数据边界上移位的所有位,例如01010101 << 1 = 10101010 01010101 >> 1 = 00101010 11111111 << 2 = 11111100 11111111 >> 2 = 00111111 的示例,移位后落在边缘的任何位迷路了。

答案 4 :(得分:1)

您没有“丢失”最后一位数字。您只是没有改变您原本认为的价值。

您以n = 0b1011开始。您将其向左移动并将结果存储到 a中,而n保持不变。然后,您将n(仍然值为0b1011)向右移动,得到0b0101

如果您将a向右移动而不是n,您会看到预期的结果。