进制数应该都有了解过,我们平常使用的最多的就是10进制数,其实就是满十进一;进制数除了十进制,还有二进制,八进制,十六进制等。而在计算机中内部使用的就是二进制,满二进一。
通过python的bin方法,可以将十进制数转换成二进制数。
我们今天说的位运算就是基于二进制的数进行运算的。创建的位运算操作有以下几种。
运算符 | 含义 | 功能 |
& | 按位与 | 如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。 |
| | 按位或 | 两个相应的二进制位中只要有一个为1,该位的结果值为1。 |
∧ | 按位异或 | 若参加运算的两个二进制位同号则结果为0(假)异号则结果为1(真) |
~ | 取反 | ~是一个单目(元)运算符,用来对一个二进制数按位取反,即将0变1,将1变0。 |
<< | 左移 | 左移运算符是用来将一个数的各二进制位全部左移N位,右补0。 |
>> | 右移 | 表示将a的各二进制位右移N位,移到右端的低位被舍弃,对无符号数,高位补0。 |
7二进制表示 | 0 | 1 | 1 | 1 |
10二进制表示 | 1 | 0 | 1 | 0 |
7&10的结果 2 | 0 | 0 | 1 | 0 |
7|10的结果 15 | 1 | 1 | 1 | 1 |
7^10的结果 13 | 1 | 1 | 0 | 1 |
~7的结果 -8 | 1 | 0 | 0 | 0 |
7<<1的结果 14 | 1 | 1 | 1 | 0 |
7<<1的结果 3 | 0 | 0 | 1 | 1 |
位运算看原理应该都可以都明白,但是不知道在哪些地方应用。
玩过单片机的知道,完成led灯的闪烁或者流水灯,需要让灯亮一会,然后灭一会,对灯的点亮和熄灭实际上就是设置IO引脚的数值,这里设置为1是亮,0表示灭。(简单来说1相当于按下电灯开关,灯亮;0表示关闭,灯灭)
如果有八个led灯的话,每次都一个个灯操作就比较麻烦,通过二进制方法,就可以一起操控八个led灯,如果不断循环,就可以实现流水灯的效果了。
00000001 第一个灯亮,其它都灭
00000010 第二个灯亮,其它都灭
00000100 第三个灯亮,其它都灭
......
10000000 第八个灯亮,其它都灭
下面是用python的方法表示看一下效果。
实物运行效果
判断奇偶数
除了上面的用法,位运算还可以判断奇偶数。一般我们都使用a%2==0来判断,除了这种方法,使用位运算也可以做到。
如果 a&1==0,那么a就是偶数,等于1就是奇数。
为什么能够实现这样的效果呢?
3用二进制表示是11,1还是1(可以看成01)。
3二进制表示 | 1 | 1 |
1二进制表示 | 0 | 1 |
3&1的结果 | 0 | 1 |
4用二进制表示是100,1还是1(可以看成001)。
4二进制表示 | 1 | 0 | 0 |
1二进制表示 | 0 | 0 | 1 |
4&1的结果 | 0 | 0 | 0 |
5用二进制表示是101,1还是1(可以看成001)。
5二进制表示 | 1 | 0 | 1 |
1二进制表示 | 0 | 0 | 1 |
5&1的结果 | 0 | 0 | 1 |
通过观察可以知道,奇数的二进制第一位都是1,偶数的二进制第一位都是0,1&1的结果是1,0&1的结果是0 ,其它位不管是什么和&0都是0,所以最终通过判断最后一位的&结果值就能够知道是奇数还是偶数了。
使用位运算求和
前几天看了一个算法题,假设 a = 7,b = 9,不使用加减法,如何求出结果值?
通过位运算就可以搞定。
7二进制表示 | 0 | 1 | 1 | 1 |
9二进制表示 | 1 | 0 | 0 | 1 |
7^9的结果 14 | 1 | 1 | 1 | 0 |
7&9的结果 1 | 0 | 0 | 0 | 1 |
通过上面的表格结果可以看出,异或操作把原本是1的地方变成0了,这个地方本来是需要往前进一位了,相当于直接砍掉了,也就是少了2.(加上本来刚好是16的) 异或是一个无进位加法。
7二进制表示 | 0 | 1 | 1 | 1 |
9二进制表示 | 1 | 0 | 0 | 1 |
7^9的结果 14 | 1 | 1 | 1 | 0 |
7&9的结果 1 | 0 | 0 | 0 | 1 |
再来看看与的操作效果,其它位都变成0了,只有进位的地方保留了下来,把结果往左移动一位刚好就是上面砍掉的数值。与可以用来获取进位。
7二进制表示 | 0 | 1 | 1 | 1 |
9二进制表示 | 1 | 0 | 0 | 1 |
7^9的结果 14 | 1 | 1 | 1 | 0 |
7&9的结果 1 | 0 | 0 | 0 | 1 |
7&9的结果左移一位(<<1)
7二进制表示 | 0 | 1 | 1 | 1 |
9二进制表示 | 1 | 0 | 0 | 1 |
7^9的结果 14 | 1 | 1 | 1 | 0 |
7&9的结果 <<1后是 2 | 0 | 0 | 1 | 0 |
14&2的结果左移一位(<<1)
14 二进制表示 | 1 | 1 | 1 | 0 |
2 二进制表示 | 0 | 0 | 1 | 0 |
14^2的结果 12 | 1 | 1 | 0 | 0 |
14&2的结果 2 | 0 | 0 | 1 | 0 |
14&2的结果 <<1 是4 | 0 | 1 | 0 | 0 |
12&4的结果左移一位(<<1)
12 二进制表示 | 1 | 1 | 0 | 0 |
4 二进制表示 | 0 | 1 | 0 | 0 |
12^4的结果 8 | 1 | 0 | 0 | 0 |
14&2的结果 4 | 0 | 1 | 0 | 0 |
14&2的结果 <<1 是8 | 1 | 0 | 0 | 0 |
8&8的结果左移一位(<<1)
8 二进制表示 | 0 | 1 | 0 | 0 | 0 |
8 二进制表示 | 0 | 1 | 0 | 0 | 0 |
8^8的结果 0 | 0 | 0 | 0 | 0 | 0 |
8&8的结果 8 | 0 | 1 | 0 | 0 | 0 |
8&8的结果 <<1 是16 | 1 | 0 | 0 | 0 | 0 |
0^16的结果16就是最终的答案
0二进制表示 | 0 | 0 | 0 | 0 | 0 |
16二进制表示 | 1 | 0 | 0 | 0 | 0 |
0^16的结果 16 | 1 | 0 | 0 | 0 | 0 |
0&16的结果 0 | 0 | 0 | 0 | 0 | 0 |
0&16的结果 <<1 是0 | 0 | 0 | 0 | 0 | 0 |
代码实现:
使用位运算求和多个数字和
题目:求1+2+3+4+...+n,要求不能使用乘除法,以及循环和条件。
有经验的话,不用循环要求和的话,只能使用递归方法,但是递归判断是否到达基线条件是需要有if条件判断的,看似好像没有办法去解决。
python中的and都知道是逻辑运算符,用来判断条件的真伪,非0 数都是True,0为False,正常情况下都是等于后面的数字。
利用这个特性,就能实现求出最终的效果了。这里还是使用了递归,如果n不为0时,会一直递归下去,程序也一直返回and右侧的n+sumNums,直到n=0时,返回左侧的0,退出递归。
最后这个题目并没有使用到位运算,实际上使用其它的编程语言是有用到的。
(全文完)
长按二维码,加关注!叶子陪你玩
欢迎转载,转载请注明出处!
欢迎关注公众微信号:叶子陪你玩编程 分享自己的python学习之路