代码之家  ›  专栏  ›  技术社区  ›  MistyD Harish Kumar Kailas

用位移位理解右移算子

  •  1
  • MistyD Harish Kumar Kailas  · 技术社区  · 7 年前

    我很难理解右移运算符。我理解左移。说我们没有

    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位,在这种情况下,我们将有 所以当我们右移1时,它超过了8位int乘以1,所以最后一位被删除,变成

    5 回复  |  直到 7 年前
        1
  •  8
  •   tkausl    7 年前

    换档不起作用

    int n=11;是1011

    这是真的,但只是故事的一半。你看,数字在你的CPU里有一个固定的大小。对于整数,这是32位,但为了更简单,让我们假设8位数字。你的11看起来像这样:

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

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

    在你移动之后,第一个位子被“移出”。没有空间来存放那一小块。另外,最后一位是“空”,我们不能存储“空”。只有一个或零个。取而代之的是,我们“移入”零点。所以你最终

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

    +-+-+-+-+-+-+-+-+
    |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|
    +-+-+-+-+-+-+-+-+
    

    对于无符号数(也称为 . 在二的补码系统中,对于有符号数,它使用所谓的 算术右移

        2
  •  3
  •   HariUserX    7 年前

    1011 101 右移后。

    111110101 右移3时 111110 ,删除粗体位11111 0 101

        3
  •  3
  •   Michael Veksler    7 年前

    有几种方法来看待它。

     00001101 (8 digits)
    

    左移一位

    000011010 (9 digits?)
    

    00011010 (8 digits)
    

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

    右移也会发生同样的情况:右边的钻头脱落。 如果原件是:

    然后在左侧添加一个位创建一个9位的值,这是不受支持的。相反,加上的零将所有位向右推一位,最右边的位将脱落,结果是

    00001101 (8 digits)
    

    另一种看待它的方法是乘法和除法。在小数中,当我们乘以10时,右边加一个零。左移类似于乘法,但对于二进制。当我们除以10时,我们去掉最右边的数字,把它放在小数部分。对于正二进制和右移,它是相同的,我们只是失去分数。

    注意,负数在C++中更复杂。例如, left shifting a negative is undefined

        4
  •  1
  •   user10957435 user10957435    7 年前

    假设我们有一个数字(我们会让它变得简单,比如 00010000 )我们想把它移到左边,它看起来是这样的:

    00010000 << 1 = 00100000
    

    我们取了一个数,把每一列的值放在列中 1

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

    现在,右班做什么?它的作用正好相反,它把x列空间中每一列的值放到它的 正确的 . 例如:

    00010000 >> 1 = 00001000
    

    01010101 << 1 = 10101010
    01010101 >> 1 = 00101010
    
    11111111 << 2 = 11111100
    11111111 >> 2 = 00111111
    

    注: 位移位将切断任何在数据边界上移位的位,如 11111111

        5
  •  1
  •   jkb    7 年前

    你开始的时候 n = 0b1011 . 你把它向左移了一点 a n 不变。然后你改变了方向 n 0b1011 )向右转 0b0101

    n