python的位运算

2019年11月4日 / 8次阅读 / Last Modified 2019年11月4日
数值计算

python虽然是很高级的脚本语言,也还是对位运算有足够的支持。当我们需要的代码功能比较底层的时候,就需要使用到这些位运算。本文介绍python支持的6种位运算!

与 & AND

符号&实现与(AND)运算。

>>> 1 & 2
0
>>> bin(1)
'0b1'
>>> bin(2)
'0b10'
>>> 0b11010010 & 0b01010101
80

与运算的结果,会按照int类型显示出来。不过,需要注意一个细节,python中的int整数,不存在范围限制,即底层并没有固定使用多少个byte来存储。因此,在进行&运算的时候,python解释器默认会采用最长byte的方式来进行运算

>>> 256 & 1  # 256 needs 2 bytes
0
>>> 255 & 1
1
>>> 65536 & 1  # 65536 need 3 bytes
0
>>> 65536 & 256
0
>>> 65536 & 65535
0
>>> 65535 & 65535
65535

有负数参与时:

>>> -1 & 2
2
>>>
>>> bin(-1 & 0xFF)  # check -1's binary code
'0b11111111'
>>> bin(2)
'0b10'

计算机存储整数的方式是补码!正数的补码就是它自己,负数的补码是其对应的绝对值数的二进制码取反再加1。-1在计算机中的二进制码为 0b11111111,与2得到的结果是 0b00000010,还是2。

或 | OR

符号 | 实现或 OR 运算。

>>> 2 | 4
6
>>> bin(2)
'0b10'
>>> bin(4)
'0b100'

当数值需要的byte数不等时,同样是采用最长byte的方式来运算OR:

>>> 256 | 1
257
>>> 65536 | 1
65537

下面是有负数是的情况,跟&运算一样,都是直接采用负数的补码来计算:

>>> -1 | 2
-1
>>> bin(-1 & 0xFF)
'0b11111111'
>>> bin(2)
'0b10'
>>> -1 | -2
-1
>>> bin(-2 & 0xFF)
'0b11111110'

非 ~ NOT

符号 ~ 用来进行非运算。

>>> ~1
-2
>>> bin(~1 & 0xFF)
'0b11111110'
>>> ~-2
1
>>> bin(~-2 & 0xFF)
'0b1'

有了~运算,就可以计算补码,请参考:python中反码和补码的计算

异或 ^ XOR

符号 ^ 用来进行异或 XOR 操作。(计算机内部做加法的时候,用XOR来获得sum bit,用AND来获得 carry bit)

>>> 1^0
1
>>> 1^1
0
>>> 0^1
1
>>> 0^0
0
>>> 123^234
145
>>> bin(123)
'0b1111011'
>>> bin(234)
'0b11101010'
>>> bin(145)
'0b10010001'

当异或两边的数据对应的byte数不一样时,依然以大的那个为准:

>>> 256 ^ 255
511
>>> 65536 ^ 1
65537
>>> 65535 ^ 1
65534

带符号左移 <<

符号 << 用来进行bit的左移操作。

>>> 1<<1
2
>>> 1<<2
4
>>> 1<<3
8
>>> 1<<4
16
>>> -1<<1
-2
>>> -1<<2
-4
>>> -1<<3
-8
>>> -1<<4
-16
>>> bin(-1 & 0xFF)
'0b11111111'
>>> bin(-2 & 0xFF)
'0b11111110'
>>> bin(-4 & 0xFF)
'0b11111100'
>>> bin(-8 & 0xFF)
'0b11111000'
>>> bin(-16 & 0xFF)
'0b11110000'

移出来的空位,用0填充。是这样吗?我们继续左移-1试试看吧:

>>> -1<<5
-32
>>> -1<<6
-64
>>> -1<<7
-128
>>> -1<<8
-256
>>> bin(-256 & 0xFFFF)
'0b1111111100000000'
>>> -1<<16
-65536
>>> bin(-65536 & 0xFFFFFF)
'0b111111110000000000000000'

当把-1左移8位的时候,低8位就全部是0了,这时计数是继续的,-128再左移1位,应该得到-256,这就是带符号左移的含义!符号位被移动到第9个bit,因为它是符号位,所以它应该在高自己的最高位,在此符号位的移动过程中,中间的bit全部位置1,正好符合了补码的要求。

带符号右移 >>

符号 >> 用来进行右移运算。

>>> -1 >> 1
-1
>>> -1 >> 2
-1
>>> -1 >> 3
-1
>>> -1 >> 4
-1

0b11111111右移不变,因为要带符号,其实是符号位保持不动的结果。

>>> 128 >> 1
64
>>> 128 >> 2
32
>>> 128 >> 3
16
>>> 128 >> 4
8
>>> 128 >> 5
4
>>> 128 >> 6
2
>>> 128 >> 7
1
>>> 128 >> 8
0
>>> 128 >> 9
0

总结一下:

  • 首先要理解,整数在计算中,是以补码的形式存在;
  • python所有的位操作,都是以补码为基础,这个细节特别是在有负数参与的时候,要注意,这一点与C语言也是一致的;
  • 当两个整数实际所占用的byte数不一致时,以大的那个为准;
  • 左移和右移,都是带符号的;
  • python位运算如果有负数参数,最后得到的结果如果依然是负数(最高位是1),解释器就显示位负数,否则就显示位整数。

-- EOF --

本文链接:https://www.pynote.net/archives/1448

留言区

《python的位运算》有1条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    位运算有一个优势,效率高! [回复]


前一篇:
后一篇:

More

麦新杰的Python笔记

Ctrl+D 收藏本页


©Copyright 麦新杰 Since 2019 Python笔记

go to top