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

Mis*_*tyD 1 c++ bit-shift

我很难理解正确的移位运算符。我了解左移,说我们没有

int n = 11; which is 1011
Run Code Online (Sandbox Code Playgroud)

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

int a = n << 1 ; so a = 10110; (simply add a 0 to the end)
Run Code Online (Sandbox Code Playgroud)

这很有意义

现在右移是我遇到的困难

int a = n >> 1
Run Code Online (Sandbox Code Playgroud)

我认为答案是01011(在前面加一个0),它又是1011,而不是101。我的问题是我们如何松开最后一位数字。

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

tka*_*usl 7

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

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

整数n = 11; 这是1011

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

+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|1|1|
+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

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

 +-+-+-+-+-+-+-+-+
0|0|0|0|1|0|1|1| |
 +-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

移位后,第一位“移出”。没有空间来存储该位。另外,最后一位是“空”,我们不能存储“空”。只有一或零。相反,我们“移入”零。所以你最终

+-+-+-+-+-+-+-+-+
|0|0|0|1|0|1|1|0|
+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

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

+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|1|1|
+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

然后右移1:

+-+-+-+-+-+-+-+-+
| |0|0|0|0|1|0|1|1
+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

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

+-+-+-+-+-+-+-+-+
|0|0|0|0|0|1|0|1|
+-+-+-+-+-+-+-+-+
Run Code Online (Sandbox Code Playgroud)

Above is true for unsigned numbers, also called a logical right-shift. On a two's complement system, for signed numbers, it uses the so-called arithmetic right-shift, which instead of shifting in zero-bits, it shifts in sign-bits. I.e. if the number is negative, hence the most significant bit is one, it shifts in one's, otherwise it shifts in zero's.