[Python学习日记-20] 彻底搞懂二进制
简介
二进制的定义
二进制与十进制的转换
简介
在介绍二进制之前我们先讲一个引子,想必大家知道长城吧,长城上面每一个岗哨都会有很多个窗口,哨顶还会放狼烟。那大家知道古时候的中国是如何通信的吗?假如,战国时期两个国家要打仗了,我们垒了城墙,每隔一段就有士兵镇守,现在有人来攻打我们了,然后我们是不是得通知其他人,有人来打我们来了?那士兵应该怎么通知呢?我帮大家想了一下几个办法:
- 派个人快马加鞭跑着去——可能来回都要1个月,可能仗都打完了
- 使用飞鸽传书——中途鸽子被人打下来了,做成了烤乳鸽
- 点狼烟发送信号——这个好像比较靠谱
没错古代就是这样子做的,还有一个比较著名的典故——烽火戏诸侯。那现在又面临一个问题了,假如现在有5000精兵来打你了,你点了根狼烟搬救兵,从东边来了10个人,西边来了10个人,20个人来了,加起来才40个人,40对5000诸葛亮来了都打不过啊。有大聪明就想到了,我们不能这么保守了,只要我一点狼烟说有人来打我们了,先来他10000人,结果来了200个敌人,我们呼啦啦来一大堆人,仗是打赢了,不过这10000人所消耗的资源是不是有点浪费啊?
这样看来我们不能只单单告诉后方有敌人来了,还要告诉后方这次来了多少人。这个时候大聪明又说我知道了!来一个人点一根,来了5000人,点5000根。到最后不用打了,自己给自己烧死了。再换个思路我们就约定,来10个人点1根,来100个人点2根,来1000个人点3根,来5000个点4根,来10000个点5根...以此类推,恭喜你,这样确实就能解决问题啦,粗略的能告诉友军来了多少敌人。
当你非常开心等着援军的时候,将军提了一个变态的要求:我们要对齐颗粒度,必须精确的告诉他一共来了多少敌人,他才安排来救援。那该如何精确传送到底有多少个敌人?最后想了一个办法:
假如我们有20个狼烟孔,狠烟孔点燃了代表有人,没点燃代表没人。
这个时候来了1个敌人,士兵点燃了1根狼烟
现在2个敌人来了,把第1个狼烟孔灭掉,点燃第2个,这样只点燃第2个孔就代表2个人
现在3个敌人来了,把第1个狼烟孔点着了就表示3个人
那如果来了4个人敌人,现在有2根狼烟都点着了只能表示3个人,表示4个人,做得到么?我们分析一下前面的0-3个人表达的形式,我们会发现一开始想用一根狼烟表达1个人,正常来说2根狼烟应该只能表示2个人,那现在居然可以表示4种状态(0,1,2,3)。看着眼下这4个敌人,用2根狼烟已经装不下他们了,那我们再点1根,同时要灭掉前面的2根,因为第3根这一根狼烟就可以表示4个敌人
接下来以此类推,烟不够了就往后多点一根,最终就出现这样的情况了
经过计算这里一共是236个敌人。到此,终于完成了你上级下达的变态要求了。现在我们借助 Python 中的 bin() 方法来验证一下这个算得正不正确,代码如下
print(bin(236))
代码输出如下:
像上述那样算是非常低效的方法,算敌人个数时,你要把每个亮的狼烟孔加起来,亮的孔越多,需要加的越多,所以算的越慢。其实也有快速算法,每个孔所代表的值就是此孔及其前面孔的多少次方,如下图所示
二进制的定义
二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一",借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹发现。当前的计算机系统使用的都是二进制系统,数据在计算机中主要是以补码的形式存储的。计算机中的二进制则是一个非常微小的开关,用“开"来表示1,“关”来表示0。
在简介中讲述的引子和二进制的理论出奇的相似。假设狠烟点燃用1表示,狼烟灭掉用0表示,那么刚刚我们用狼烟表示百万雄师的理论就可以用在计算机上,这种表示数字的方式就叫做二进制。
你可能会觉得发明计算机的人思路轻奇,为什么要多此一举的用这种方式来表达数字,但事实上计算机不像我们这样智能,CPU 是一个包含上亿个精巧的晶体管的芯片集合,晶体管表达的方式很简单,就是通过高低电压(有电没电),低电压的时候表示0,高电压的时候表示1,因此最终能让计算机理解的就只有0和1而已
二进制与十进制的转换
在简介的引子中其实我们已经进行过这一过程了,刚才已经发现,二进制的第 n 位代表的十进制值都刚好遵循着2的 n 次方这个规律,但是在进行人工转换时2^7等于128这种计算有时候也很难反应过来,如果借助计算机就没有这个烦恼了 Python 中可以借助 int() 和 bin() 来进行十进制和二进制转换
print(int(0b10100)) # 十进制20,在写二进制时一定要在前面加 0b
print(bin(200))
代码输出如下:
当然我们也不能忽略人工计算,这里我们可以先列出 2的 n 次方的好几位出来,然后逐个进行填位,如下图所示
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
20 | 1 | 0 | 1 | 0 | 0 | |||
200 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 |