zca*_*dqe 6 python bit-manipulation
我试图理解>>对负整数的位移操作。
-2 >> 1 # -1
-3 >> 1 # -2
-5 >> 1 # -3
-7 >> 1 # -4
Run Code Online (Sandbox Code Playgroud)
有人可以解释这是如何完成的吗?我知道它与二进制补码有关,但我无法将其与移位操作联系起来。
此处提供完整说明
负整数的二进制补码:
负数用前导一而不是前导零书写。因此,如果您只使用 8 位作为二进制补码,那么您可以将从“00000000”到“01111111”的模式视为从 0 到 127 的整数,并保留“1xxxxxxx”用于写入负数。使用 (x-1) 的位模式写入负数 -x,所有位都进行补码(从 1 到 0 或 0 到 1)。所以-1 是补码(1 - 1) = 补码(0) = "11111111",-10 是补码(10 - 1) = 补码(9) = 补码("00001001") = "11110110"。这意味着负数一直下降到 -128(“10000000”)。
当然,Python 不使用 8 位数字。它曾经使用您的机器本机的许多位,但由于这是不可移植的,它最近切换到使用无限数量的位。因此,按位运算符将数字 -5 视为写成“...11111111111111111111011”。
所以,移位运算符的解释:
x >> y 返回 x 右移 y 位的位。这与 //'ing x by 2**y 相同。
为了理解上面的解释,你可以用这样的东西来检查它:
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)
Run Code Online (Sandbox Code Playgroud)
哪些输出:
-10 >> 1 = -1 <==> 11111110 >> 1 = 11111111
-11 >> 1 = -10 <==> 11111101 >> 1 = 11111110
-101 >> 1 = -11 <==> 11111011 >> 1 = 11111101
-111 >> 1 = -100 <==> 11111001 >> 1 = 11111100
Run Code Online (Sandbox Code Playgroud)
如您所见,数字的二进制补码将扩展符号。