编码的本质及计算机的工作原理

     原文发表于我的微信公众号"涛歌依旧",可以点击如下红色文字链接阅读:

   编码的本质及计算机的工作原理(链接)

      从微信公众号把原文直接复制过来,发现图片经常丢失,只有纯文字,所以建议直接点击上述链接阅读。

      复制过来的纯文字内容如下(图片丢失):

       小时候,很喜欢骑自行车,经常和伙伴们一起骑车玩耍和比赛。那时,个头还不如自行车高,采取下面这种姿势骑自行车,玩得不亦乐乎,此皆幼时闲情也。时光一去不复返,涛哥也人到中年。


       不需要读什么书,也不需要什么知识,我们就能大致悟出自行车的工作原理。这些原理,基本上就是常识:
        1.  用力踩呀踩,中间那个铁齿轮开始转动。
        2. 通过链条,带动后轮转动。
        3. 然后推动前轮转,走起。
       这个原理描述,并不十分精准,但足够让人了解自行车的工作原理。

       有的朋友要说,会骑自行车就行了,管它什么工作原理。这句话,听起来好有道理。可是,林语堂先生却说:光知道用东西,却不知其所以然,实在很悲哀。


       后来,台湾知名技术作家侯杰先生,在他的著作《深入浅出MFC》中,也提到了上述观点。
       我个人的观点是: 我们使用工具,并不是一定要深究其原理,有时候,没有必要浪费精力和时间,沉迷于不重要的细节。但是,如果能了解一些原理,能帮助我们更好地使用和修复工具,甚至是改进和创造工具。

       如今,我们几乎所有的人,每天都在使用计算机(手机也是计算机)。对于大多数人而言, 没有必要深入了解计算机的工作原理。而对于从事计算机相关行业的人,或者对计算机有兴趣、有好奇心的人,是可以去了解一下的。 另外,了解计算机的工作原理,也能为装叉吹牛增加一些信心和谈资。说不定帮人修电脑或者安装系统时,侃侃而谈,还能成就一段美好姻缘(身边有这样的例子)。
        
       我们可以不了解自行车相关的知识,可以不了解牛爵爷的经典力学,却也能搞懂自行车的工作原理。 但是,如果不了解计算机相关的知识和思想,绝对没有任何可能搞懂计算机的工作原理。因为,经历从各层硬件到各层软件的层层抽象后,计算机内部已经复杂得让人难以想象。
       比如芯片,指甲那么大,却有几亿甚至几十亿个晶体管电子器件,每个晶体管电子器件的电流和电压,在1秒内,能变化几亿甚至几十亿次。学过排列组合的朋友,应该知道,芯片内部每时每刻的状态数量,是一个天文数字。


      再比如操作系统,以谷歌公司的Android系统为例,少说点也有1亿行代码。假设一本书有500页(正反算两页,这已经是一本很厚的书了), 书的单面印50行代码,那么一本书就能印刷25000行代码。如果把操作系统的代码都印刷在书上,那就是4000本书,我的天。


       4000本密密麻麻写满代码的书,而不是网上成功学大忽悠们吹嘘的孙正义看的那4000本书:

       当我们拿着手机,聊微信、逛淘宝、刷抖音时,我们是否意识到发生了什么呢?

      通过手机app、中间件、操作系统、驱动程序,我们在操纵着手机芯片中的电压和电流,操纵着芯片中的无数分子中的原子中的电子。

       我们还利用了麦克斯韦电磁场理论,通过电磁场和电磁波的方式,远程操纵着马化腾的服务器、马云的服务器、张一鸣的服务器的芯片中的无数分子中的原子中的电子。真有点武侠小说的感觉,手指在手机上轻轻一滑,世界各地的计算机芯片中的电子为之一振。

       是的,从微观层面讲,那些电子在杂乱无章地“乱窜”,充满着不确定性。但是,通过抽象,我们拥有了宏观层面确定的欧姆定律、基尔霍夫定律。然而,电流电压依然会存在上下轻微波动,并不准确,于是通过再次抽象,我们拥有了确定的与或非门电路;通过再次抽象,我们拥有了确定的芯片;通过再次抽象,我们拥有了确定的驱动程序、操作系统、中间件;最后,我们拥有了确定的、带功能意义的应用程序/app,  于是乎,我们滑动着手机,玩着,乐着。

       计算机,从顶层的应用程序往下看,处处都有抽象,处处都是编码和转换。我们没有办法,也没有必要弄清计算机的每个细节,但只要把握住了计算机的工作原理,弄清一些核心概念,还是能在一定抽象度上搞懂计算机。

       抽象,是计算机科学和技术中最重要的思想,没有之一。抽象的重要性,在操作系统中的体现尤为明显。

       通过层层抽象,我们才可以轻松地聊微信、逛淘宝、刷抖音, 而最背后的最底层,不过是芯片中的电子在“乱窜”而已。

      我们似乎了解了一点计算机的工作原理,但略感模糊,所以还需要继续探索与追问。
     计算机中所有一切的工作和行为,都可以归结于计算。当我们在聊微信、逛淘宝、刷抖音时,都是通过计算机(手机)的芯片计算来实现的。
      既然都是通过计算来实现,那我们就要弄清计算机的计算原理。先来看看计算机中最简单的加法运算是如果做的吧, 这还得从编码说起。

      什么是编码?编码的本质又是什么?对于通信专业同学而言,第一反应可能是到信号编码,而对于计算机专业同学而言,第一反应很可能是写代码。这两种理解,都局限在特定专业领域内。事实上,编码是广义的,无处不在。
      在战争中,联络的暗号,是一种编码。如果不懂之前的约定,就无法知道暗号的具体意思,这个“知道”的过程,就是解码。
      在生活中,使一个眼色,也是一种编码,把想法用眼色来表示。我们经常说:我不懂你说的意思。 其本质意思就是:我无法解码你说的意思。
      很多信息,都是编码与解码的过程。来看图:


       一图胜千言,我们可以得出如下结论:
       1. 观察A和B,  对于同一事物,如果编码方式不同,那么得到的结果也不同。
       2. 观察B和C,  对于不同事物,经编码后,可能得到相同的结果, 但他们的含义是不一样的。要解码一个东西,必须知道它曾经采用了哪种编码方式,否则无法解码。
      上述1和2这两种现象,在现实生活中无处不在。我们由此也可以得知:编码的本质,就是映射。解码的本质,就是去“理解”,是一个反过程。他们必须配套使用,否则行不通。


      为什么我们费尽心思去讲编码的本质呢?因为通信的本质,就是编码并传输,计算机的本质,就是编码并处理。我们先来看一幅图:

      我们可以看到,从苹果到数字,是一种编码方式,从数字到苹果,是对应的解码。而且,上述的编码,是我们很熟悉的阿拉伯十进制编码。
      十进制编码由来已久,本质上就是因为,人有十个手指,这一点,我们在上一篇文章已经讲过。


      以“109个苹果”为例,我们用十进制和二进制分别对其进行编码:

      可以看到,十进制编码后,数字都是由0,1,2,3,4,5,6,7,8,9这十个数字组成的。而二进制编码后,数字都是由0,1这两个数字组成的。
       这里,我们再次看到:
      1. 对于“109个苹果”,当编码方式不同时,其编码后的结果自然不相同。
      2. 对于1101101,如果不知道它是由什么方式编码而来的,我们就没法理解它。如果是二进制编码,就会被理解为是“109个苹果”。万一按照十进制去理解,那就是“一百一十万一千一百零一”个苹果,这显然是不对的,究其原因,就是编码的时候,用了二进制编码,但解码的时候,用了十进制解码,自然不行。
      在上面的结果中,对于1101101,为了不至于理解错误,我们用1101101B来表示这个数是用二进制编码的结果,这个B就是binary digit的缩写,意思是二进制,解码后就是“109个苹果”。
      而对于不标注B的数字109, 我们默认它就是用十进制编码的结果,  解码后就是“109个苹果”。


      下面,我们来看下加法计算:

      一目了然,很简单。可以看到,二进制数字只有0,1两个数位,做加法时,满二进一。
      由此可见,无论是十进制编码,还是二进制编码,他们都是等价等效的。实际上,还可以编码为三进制、四进制、...、十五进制、十六进制、十七进制等其他进制。
        

       众所周知,现代计算机采用的是二进制逻辑,但是,为什么计算机要采用如此反人性的二进制呢?我们来慢慢说。

       先来看“14个苹果”加“38个苹果”这件看似简单的事情, 我们该怎样用电路来完成计算呢?

       首先,需要把苹果编码成数字,即14和38这两个数字。

       然后,需要把14和18编码成14v和18v, 也就是用电压表示数。

       最后,把结果52v解码理解成数字52,也就对应“52个苹果”。

       我们先来看看,用电来表示数,并实现加法,以14加38为例,输入14v的电压和38v的电压,设计电路,实现电压相加,得到52v,完全可以。可是,如果是9999加8888呢?用9999v和8888v的电压?估计这个加法器早就被烧糊了,器毁人亡。

       我们来改进设计方案,下面这个设计就靠谱很多了,一根电线上的最低电压是0v, 最高电压是9v, 不至于把器件烧毁,人也安全。下面这个十进制加法器,貌似很完美了。事实上,最初,人们造计算机的时候,用的就是十进制。

      

       可是,现在有三个必须要面对和解决的问题:

       其一,怎么实现4v+8v=12v呢?把两个电压串联起来,结果不就是电压之和吗?可是,这毕竟不是两个电池啊,貌似不太好串联。想了很久,也没有找到比较好的办法。

       其二,从0v到9v, 总共有10个电压位,由于电子线路器件的原因及其内部复杂性,如果一根电线的电压值是7.49v,  那么,请问,它表示的是数字7还是数字8呢?这是很尴尬的事情,容易混淆。

       其三,如果要去计算14.001加上38.002, 用电路该如何表示呢?如何计算出准确无误的52.003 ? 要知道,任何一点电压的波动,都可能让最近的结果产生偏差。

       有没有更好的设计方式呢? 从莱布尼茨到布尔,再到香农,都在苦苦探索着。最后探索出了解决之道:可以使用二进制来计算,然后用电路来实现二进制计算。

       用电路来实现二进制表示和二进制计算,我们今天看起来似乎很简单,但探索出这条路,并不容易。

       莱布尼茨发明了二进制,但他在做自己的乘法器时,并没有意识到二进制的重要性。关于莱布尼茨,我们在上一篇文章中已经简要介绍过。莱布尼茨终生未婚,在科学和哲学史上,他真可谓是百科全书式的人物。

       布尔创建了逻辑代数,也称布尔代数,在很大程度上, 为后来的电路设计及其简化,做出了很大的贡献。现在很多编程语言中都内部了布尔类型,以纪念这位先驱。1864年,在暴风雨中,布尔淋湿了,还坚持去上课,然后肺炎复发,一命呜呼了,真是可惜。希望大家注意身体,生病了,要休息。累了,要休息。另外就是,不要参加或观看《追我吧》之类的无聊节目。

       香农,正是香农,最先洞察到了开关系统和布尔逻辑之间的关系,并发表了论文《继电器和开关电路的符号化分析》,可以说,这篇文论让人们意识到,可以用电路来实现二进制表示和二进制计算。香农活到了二十一世纪,当他看着这个世界,因为他的贡献而变得如此美好时,内心一定是很欣慰的。作为电子通信专业的学生(现在不搞这块了),我对香农真是佩服得五体投地。

       继续回到正题,反思一下上面的设计,问题就在于电压位太多,导致0v和9v中间插入了太多的电压位,相邻电压位容易错乱干扰,不准确。

       联想一下前面提到的二进制,能不能用二进制来计算呢?

      把0编码成0v, 把1编码成9v, 也就是用0v标志0,用9v表示1,完全可以的,看设计图:

       这样,即使电压出现了略微的偏差,比如出现8.4v, 我们也认为它是9v产生的偏差,所以可以判定出,它是9v, 对应二进制的1. 同理,如果出现1.6v, 我们也知道,这是0v出现了偏差,所以可以判定出,它是0v,对应二进制的0.

       由此可见,引入只有0v,9v这两个电压位后,系统会更稳定可靠,出错的可能更小。两个电压位的加法,其实就是二进制加法。二进制中的0用0v来表示,二进制中的1用9v来表示。

       至于14.001加38.002,要实现准确计算也很简单,无非就是多加几根电线,专门表示001和002,跟整数加法的逻辑类似。这样一来,0.001和0.002就是准确的值了,不怕电压波动干扰。

       

      上面是6位二进制数字和6位二进制数字相加的加法器,要用电路实现这个功能,首先就要用电路实现1位二进制和1位二进制相加的加法器, 也就是说, 我们需要做一个下图中的“神秘电路”:

       这个“神秘电路”难吗?感觉不太难,但似乎也不怎么好用电路来实现。别着急,这个“神秘电路”的具体实现,我们将在后续文章中揭晓。提前剧透一下,这个“神秘电路”,其实就是“半加器”(不含进位功能)。

     

       到此为止,虽然我们没有完整地设计出加法器的具体电路,但对计算机的计算原理,应该有比较深刻的认识了。计算机的计算本质,就是将要计算的数字,进行二进制编码,然后用对应的电路的高低电压(如9v和0v)来表示,通过电路的逻辑功能,从电路的输出中得到高低电压,进而理解为二进制,并最后转化为数字,作为结果。

       需要注意的是,高低电压(如9v和0v),在数字电路中,经常被称为高电平(表示二进制数字1)和低电平(表示二进制数字0)。下次我们提到高电平时,意思就是,这个电压表示二进制数字1, 而提到低电平时, 意思就是,这个电压表示二进制数字0.

       那么,高电平和低电平一定是9v和0v吗?显然不一定。 我们也可以把高低电平,分别定义为5v和0v,完全可以。在后续文章中,用proteus进行仿真时,我们主要用5v来表示高电平(二进制数字1),而用0v来表示低电平(二进制数字0)。 

       这样,就实现了用电路来计算二进制。有了编码和计算,我们才能让计算机,呈现出丰富多彩的功能,这就是计算机的工作原理。

       上面提到了香农, 这里补充说一下, 香农更有名的一篇论文是《通信的数学原理》,学过通信的人,不能不知道这篇论文。作为信息论的创始人,香农当之无愧。

       在知乎上,曾经看到这样一个问题:为什么没有给伟大信息论开山泰斗---香农颁发图灵奖? 挺有意思的,截图如下:

       写到这里,本文也快接近尾声了。我们首先简要地介绍了计算机的工作原理,又讲了编码的本质和二进制编码,然后讲了二进制编码的好处,最后从设计图的角度,实现了二进制加法。

       在后续文章中,我们将会讲到计算机中加法的具体实现,并且会进行实际电路的仿真,用电路来完成加法,到时会顺便搞定上面提到的“神秘电路”---“半加器”。

      

        期待我们自制的计算机加法器

        不见不散

发布了2213 篇原创文章 · 获赞 4564 · 访问量 1977万+

猜你喜欢

转载自blog.csdn.net/stpeace/article/details/103317663