负整数的位移?

时间:2016-09-17 17:50:34

标签: python bit-manipulation

我试图理解负整数上的位移操作>>

-2 >> 1 # -1
-3 >> 1 # -2
-5 >> 1 # -3
-7 >> 1 # -4

有人可以解释一下这是怎么做到的吗?我知道它与Two的补充有关,但我无法将其与转换操作联系起来。

1 个答案:

答案 0 :(得分:3)

提供完整说明here

  

负整数的两个补码二进制文件:

     

负数用前导而不是前导来写   零。因此,如果您的二进制补码仅使用8位   数字,然后你处理来自" 00000000"到" 01111111"作为   整数从0到127,并保留" 1xxxxxxx"写作   负数。使用该位写入负数-x   (x-1)的模式,所有位都被补充(从1开始切换)   到0或0到1)。所以-1是补码(1 - 1)=补(0)=   " 11111111",和-10是补体(10-1)=补体(9)=   补(" 00001001")=" 11110110"。这意味着负数   一直到-128(" 10000000")。

     

当然,Python不使用8位数字。然而,它用于使用   很多位都是你的机器的原生,但从那以后   非便携式,它最近切换到使用INFINITE数量   位。因此,数字-5由按位运算符处理,就好像它一样   书面" ... 1111111111111111111011"。

所以,移位运算符的解释:

  

x>> y返回x,向右移动y位。这个   与// @ x * 2相同。

为了理解上述说明,您可以查看以下内容:

def twos_comp(val, nbits):
    """Compute the 2's complement of int value val"""
    if val < 0:
        val = (1 << nbits) + val
    else:
        if (val & (1 << (nbits - 1))) != 0:
            # If sign bit is set.
            # compute negative value.
            val = val - (1 << nbits)
    return val

def foo(a,b):
    print("{0:b} >> {1:b} = {2:b} <==> {3:b} >> {4:b} = {5:b}".format(
        a,b,a>>b,
        twos_comp(a,8),b, twos_comp(a>>b,8)
    ))

foo(-2, 1)
foo(-3, 1)
foo(-5, 1)
foo(-7, 1)

哪个输出:

-10 >> 1 = -1 <==> 11111110 >> 1 = 11111111
-11 >> 1 = -10 <==> 11111101 >> 1 = 11111110
-101 >> 1 = -11 <==> 11111011 >> 1 = 11111101
-111 >> 1 = -100 <==> 11111001 >> 1 = 11111100

正如您所看到的,该数字的两个补码将扩展该符号。