Python位运算符(逻辑积、逻辑OR、排他OR、倒置、移位)。

商业

Python提供了下列位操作符,它们分别对二进制整数类型int值的每一位进行逻辑结合、逻辑分离、排他分离、位反转、左移位和右移位。

  • &
  • |
  • ^
  • ~
  • <<
  • >>

在本节中,我们首先解释如下。

  • 交叉点 (AND) : &
  • 分歧点 (OR) : |
  • 排他性-OR操作 (XOR) : ^

接下来,我们将讨论以下内容。

  • 对负整数的位操作
  • 位数翻转 ( NOT) : ~
  • 位移 : << , >>

关于如何用二进制、八进制和十六进制写整数,以及如何使用以下函数转换二进制、八进制和十六进制数字和字符串的更多信息,请参见以下文章。

  • bin()
  • oct()
  • hex()
  • format()

另外,对于布尔值(真、假)的逻辑操作(布尔操作),而不是位操作,请参考以下文章。使用and,or而不是&,|。

交叉点 (AND) : &经营者

这是一个使用&操作符进行逻辑和的例子,结果由bin()转换为二进制符号的字符串。

x = 9   # 0b1001
y = 10  # 0b1010

print(x & y)
print(bin(x & y))
# 8
# 0b1000

分歧点 (OR) : |经营者

一个使用|运算符的逻辑乘积(OR)的例子,其结果通过bin()转换为二进制符号的字符串,并一起输出。

print(x | y)
print(bin(x | y))
# 11
# 0b1011

排他性-OR操作 (XOR) : ^经营者

使用^运算符的逻辑乘积(XOR)的例子,结合使用bin()转换为二进制符号的字符串的结果。

print(x ^ y)
print(bin(x ^ y))
# 3
# 0b11

逻辑AND、OR和XOR的每一位的输入和输出的关系如下表所示。

输入1输入2交叉点 (AND)分歧点 (OR)排他性-OR操作 (XOR)
11110
10011
01011
00000

对负整数的位操作

当对一个负整数进行位操作时,该值的处理就像它以2的补码形式表示一样。

然而,请注意,如果你用bin()或format()将一个负整数转换为二进制字符串,绝对值将有一个减号,而不是二进制补码的格式。

如果你想得到一个用二补表示的字符串,就用所需的最大位数进行AND,如下图所示。

  • 对于4位0b1111 (=0xf)
  • 对于8位0xff
  • 对于16位0xffff

你可以得到一串二进制的补码表示(每个比特都被倒置,并加上1)。

x = -9

print(x)
print(bin(x))
# -9
# -0b1001

print(bin(x & 0xff))
print(format(x & 0xffff, 'x'))
# 0b11110111
# fff7

位数翻转 : ~经营者

~用运算符翻转位子的例子。

位反转并不是简单地将每个位的值反转。使用该运算符时的返回值如下。
~x=-(x+1)

-(x+1)这个值相当于把输入值x看成是二的补码形式,并把所有的位都倒置。

如上所述,在Python中,当一个负整数使用bin()、format()等转换为二进制字符串时,它不是以二补的形式,而是以带减号的绝对值。因此,直接将 ~x 转换为字符串不会产生一个将原值的位数倒置的字符串。

x = 9  # 0b1001

print(~x)
print(bin(~x))
# -10
# -0b1010

当我们进行AND操作并将其转化为一串二的补码表示时,我们可以看到原值的比特被倒置了。

此外,例如,为了得到一个4位数的位串,按原样倒置(省略符号位),使用format()为ANDed值填入0,如下所示'04b'

print(bin(~x & 0xff))
print(format(~x & 0b1111, '04b'))
# 0b11110110
# 0110

位移 : << , >>

使用位移运算符进行左位移和右位移的例子。

x = 9  # 0b1001

print(x << 1)
print(bin(x << 1))
# 18
# 0b10010

print(x >> 1)
print(bin(x >> 1))
# 4
# 0b100

对于负值,符号位被扩展和移位,而正负符号保持不变。负值是一路向左的1行的图像。

x = -9
print(bin(x))
print(bin(x & 0xff))
# -0b1001
# 0b11110111

print(x << 1)
print(bin(x << 1))
print(bin((x << 1) & 0xff))
# -18
# -0b10010
# 0b11101110

print(x >> 1)
print(bin(x >> 1))
print(bin((x >> 1) & 0xff))
# -5
# -0b101
# 0b11111011

最好用二补表达式的字符串来思考,因为用数字来思考并不清楚。