数字类型实战——按位运算

未匹配的标注

除了普通的数字运算(加法、减法等),Python还支持C语言中可用的大多数数字表达式。这包括将整数视作二进制位字符串的操作符,而且如果Python代码必须处理像网络数据包、串口或被C程序生成的打包好的二进制数据这些情形的话,这会很方便。

这里不能详述布尔数学的原理——再说一次,那些必须使用它的人很可能已经知道它如何工作的了,而其他人通常可以完全推迟这个主题——但基础是很简单易懂的。比如,下面是实践中一些Python的按位表达式操作符,它们对整数执行按位移动和布尔操作:

>>> x = 1 # 十进制的 1 在比特位中是 0001
>>> x << 2 # 向左移动2个比特位:0100
4
>>> x | 2 # 按位或 (只要有一个比特位=1,结果就为1): 0011
3
>>> x & 1 # 按位与 (两个比特位同时=1,结果才位1): 0001
1

在第一个表达式中,二进制的 1(底数为2,0001)被往左移动两位从而创建了二进制的4(0100)。最后两个操作执行了二进制 OR来合并比特位(0001|0010 = 0011),和二进制 AND来选择共同的比特位(0001&0001=0001)。这些比特位屏蔽操作允许使用一个整数来编码和提取多个标记和其他值。

这是Python中的二进制和十六进制数字支持从版本3.0和2.6开始变得特别有用的一个地方——允许使用比特位字符串来编码和检查数字:

>>> X = 0b0001 # 二进制字面量
>>> X << 2 # 往左移动
4
>>> bin(X << 2) # 二进制数字符号字符串
'0b100'
>>> bin(X | 0b010) # 按位或: 其中一个为1即为1
'0b11'
>>> bin(X & 0b1) # 按位与: 两个同时为1才为1
'0b1'

这对一开始作为十六进制字面量,或经历进制转换的值也是适用的:

>>> X = 0xFF # 十六进制字面量
>>> bin(X)
'0b11111111'
>>> X  0b10101010 # 按位异或: 只能有一个为1
85
>>> bin(X  0b10101010)
'0b1010101'
>>> int('01010101', 2) # 数字符号=>数字: 根据底数将字符串转换为整数
85
>>> hex(85) # 数字=>数字符号: 十六进制数字符号字符串
'0x55'

同样在这方面,Python 3.1和2.7引入了一个新的整数的 bit_length方法,它允许查询需要多少比特位数来以二进制表示数字值。通过bin字符串的长度(使用第4章中见过的len内置函数)-2(考虑到前导”0b“)通常可以达到同样的效果,虽然可能不那么高效:

>>> X = 99
>>> bin(X), X.bit_length(), len(bin(X)) - 2
('0b1100011', 7, 7)
>>> bin(256), (256).bit_length(), len(bin(256)) - 2
('0b100000000', 9, 9)

这里将不会过深地研究这些”bit操作“。如果需要,它是被支持的,但按位操作在像Python这种高级语言中通常不如像C语言这种底层语言中那么重要。作为一个经验法则,如果发现自己在Python中倒腾比特,就应该考虑下实际上是用哪种语言进行编码。后面章节会看到:Python的列表,字典还有类似的其他东西都提供了比位字符串更丰富——通常更好的——方法来编码信息,特别当数据受众包括人类读者时。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~