Python3.X中的位运算符

什么是位运算符
位运算是直接对整数在内存的二进制位进行操作。

什么是二进制
二进制,是一种广泛应用于现代计算机技术的数制,进位规则是“逢二进一”,借位规则是“借一当二”。

如何把十进制转化成二进制
以2017为例,2017十进制可以分解成

2017 = 2*10³ + 0*10² + 1*10¹ + 7*10⁰

它的二进制是11111100001⁰¹²³⁴⁵⁶⁷⁸⁹

111 1110 0001 = 1*2¹⁰ + 1*2⁹ + 1*2⁸ + 1*2⁷ + 1*2⁶ +1*2⁵ + 0*2⁴ + 0*2³ +0*2² + 0*2¹ + 1*2⁰
=1024 + 512 + 256 + 128 + 64 + 32 + 0 + 0 + 0 + 0 + 1
=2017
正整数转二进制

“除二取余,倒序排列,高位补零”就是正整数转二进制的方法。
这里通过一个流程图来演示:9转化为二进制的最终结果是1001。

这里写图片描述

负整数转化二进制
“正数计算,反向取值,结果加一”

Python中位运算符

符号描述
&按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
|按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
^按位异或运算符:当两对应的二进位相异时,结果为1
~按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1
>>左移动运算符:运算数的各二进位全部左移若干位,由”<<”右边的数指定移动的位数,高位丢弃,低位补0。
>>右移动运算符:把”>>”左边的运算数的各二进位全部右移若干位,”>>”右边的数指定移动的位数

1、& 运算符
通常用于二进制取位操作,其 &1 的结果可以用来判断数字的奇偶性,若结果是0则是偶数,是1则是奇数。

>>> 22&1
0
>>> 13&1
1

2、| 运算符
通常用于二进制特定位上的无条件赋值,其 |1 可以把二进制的最末尾强制变为1,实际上就是把一个数变为最接近的奇数,如果变为偶数,只需要 |1 后 加1减1 即可。

>>> 220|1
221
>>> 33|1
33

3、^ 运算符
^ 运算符可以用作简单的加密, ^ 运算的逆运算是它自身,那就意味着一个数2次异或同一个数,结果不会发生改变。


>>> 2017^888^888
2017

^ 运算符还可以做两个数字的交换,类似 + - 运算的结果。

a=2017 b=1993 a=a+b b=a-b a=a-b 结果a=1993 b=2017

位运算如下

a = 2017
b = 1993
a = a^b
b = a^b
a = a^b
print('a = ',a)
print('b = ',b)

^ 运算符版本的交换两数不适用于一个数的自我交换。如果上述程序的“b”改成“a”的话,其结果是变量a=0。所以,在使用快速排序时,由于涉及到一个数的自我交换,如果要在其中使用位运算版的交换两数的话,应该先判断。

4、<< 运算符

a << b相当于把 a 的二进制整体左移 b 个位置后补 b 个 0 。

例如:10 << 5
10 的二进制是 1010
100<<2 后的二进制式 101000000 等于 320
相当于 10 乘以 2 的 5 次方
通过上面的实例,可以得出,每向左移动1位相当于该数乘以2。通常来说,位运算更加底层,效率更高,因此程序中 * 2 的操作尽可能的用左位移来代替。
定义一些常量可能会用到 << 运算。 可以用 (1<<16)-1 来表示65535。很多算法和数据结构要求必须式2的幂,此时可以用 << 来定义常量。

6、>> 运算符
和 << 相似,其相当于除以 2 的 b 次方,取整。我们可以使用 >> 来代替二分查找、堆的插入操作等。

功能示例位运算
去掉最后一位(101101->10110)x >> 1
在最后加一个0(101101->1011010)x << 1
在最后加一个1(101101->1011011)x << 1+1
把最后一位变成1(101100->101101)x | 1
把最后一位变成0(101101->101100)x | 1-1
最后一位取反(101101->101100)x ^ 1
把右数第k位变成1(101001->101101,k=3)x | (1 << (k-1))
把右数第k位变成0(101101->101001,k=3)x and not (1 << (k-1))
右数第k位取反(101001->101101,k=3)x ^ (1 << (k-1))
取末三位(1101101->101)x & 7
取末k位(1101101->1101,k=5)x & (1 << k-1)
取右数第k位(1101101->1,k=4)x >> (k-1) & 1
把末k位变成1(101001->101111,k=4)x | (1 << k-1)
末k位取反(101001->100110,k=4)x ^ (1 << k-1)
把右边连续的1变成0(100101111->100100000)x & (x+1)
把右起第一个0变成1(100101111->100111111)x | (x+1)
把右边连续的0变成1(11011000->11011111)x | (x-1)
取右边连续的1(100101111->1111)(x ^ (x+1)) >> 1
去掉右起第一个1的左边(100101000->1000)x & (x ^ (x-1))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值