如何只用0和1创造全世界?

或许你听过这样一种说法,计算机眼中的世界只有0和1

你每天在电脑或者手机的屏幕上看见的只有文字、图片或者视频等等,唯独没有计算机眼中的0和1。对此,你有没有对上面的话表示过怀疑,计算机眼中的世界真的只有0和1吗?如果是真的,那你在屏幕中所看见的一切又是如何通过0和1变化出来的呢?

要回答上面两个问题,我们可以先回到之前所写的原始人是如何计数的?故事中。在里面你作为一个聪明的原始人,为了能够记录自己捕捞的鱼数,发明了十个符号和一套规则。

这些符号与你平时使用的阿拉伯数字可以一一对应。

这套规则也就是你平时所使用的十进制计数法。

接下来,我想额外给你增加一些限制条件,如果你只能使用两个符号来计数,现在你要怎么办?

既然只能使用两个符号,你可以从原本的十个数字中任意选择两个,例如选择0和1。或者你也可以重新发明两个符号,例如三角和方形。

确定好了符号,接下来就需要重新创造一套规律,利用这两个符号来表示不同的鱼数。

假如,你第一天没有捕到鱼,第二天捕到了一条鱼,这两种情况正好可以使用你选出的两种符号来表示。

接着,你每天捕到的鱼数都会比上一天多一条,你要如何使用两个符号来表示2~10这几个数字呢?

实现的方法很简单,与十进制的规则类似,当某个位置的符号用完时,只需要在它的左边增加一个符号即可。

它们的区别是,十进制的每个位置有十个符号,可以表示十个数字。现在你每个位置只有两个符号,只能表示两个数字。

上面这种用0和1两个符号表示数字的方式也就是二进制计数法。

在这里我给你留一个小小的思考题。你可以想一想,有没有什么计算方法,可以将一个数在二进制和十进制之间互相转换?

利用上面的规,你已经可以表示出十进制中的所有自然数。自然数只是整数中的一部分,整数中除了自然数(正整数和0),还包括负整数。

如何用0和1表示负整数呢?

在十进制中,你是通过将两个符号 “+” 和 “-” 放在数字的左侧来区分正数和负数。通常情况下 “+” 号可以省略不写。

现在你想要在二进制数上区分正数和负数,是不是也需要在数字前面增加两个符号作为区分?正巧你现在就拥有两个符号0和1。

你只需要改变一下之前的规则,将每个二进制数最左边的那个符号用来表示正号或负号,例如用0代表 “+” ,用1代表 “-”,现在你就用0和1表示出了所有的整数。

继续往下想,你知道除了整数之外,还有小数,应该如何用0和1表示呢?

我猜你看到上面用0和1表示正负号以后,脑子里面马上就会想到用0或1来表示小数点。此时你会遇到一个问题,当一个代表小数点的符号放在两个代表数字的符号中间时,你要如何区分哪个符号是小数点呢?

例如,你用0来代表小数点,此时二进制的0101应该表示+1.1还是表示+5呢?

想一想小数点在十进制中的作用是什么?是不是用来让你区分一个数字中,哪一部分属于整数,哪一部分属于小数?

类似的操作,假如你提前固定好一个二进制数的符号个数,例如使用8个01符号代表一个数。你可以将这8个符号分成3个部分,例如规定最左边的第一个01代表正负号,左数第2至第4个01代表整数部分,剩下的第5至第8个01代表小数部分。这样一来,你是不是就可以用一个8位二进制数来表示一个小数了。

除了上面的表示规则之外,还有另一种更利于计算的表示规则。

类似于一个十进制数,它是将每个位置数的乘方形式相加的和。

一个二进制数也可以表示为每个位置数的乘方形式相加。区别是十进制的底数为10,二进制的底数为2。

同样还是把最左边的第一个01代表正负号,左数第2至第4个01代表整数部分,剩下的第5至第8个01代表小数部分,上图的两个二进制数就可以表示为下面这两个小数。

利用上面两种规则,你已经可以用0和1表示出一个小数,但是它们都存在一个问题。

计算机在处理一个二进制数时,它所使用的符号个数会有限制。当你给电脑安装操作系统或者软件时,你需要先确定好操作系统的位数,例如32位或者64位。这里的32和64就是计算机一次最多能处理的01符号的个数。

假设你用的是32位的操作系统,去掉最左边的符号位后,还剩下31位来表示数字。假如将它们全部用来表示整数的话,转换成十进制的数字范围就是-2,147,483,648 ~ 2,147,483,647。

现在你为了表示小数,又将剩余的31位分成了整数和小数两部分,可想而知每部分所能表示的数字的取值范围就变得更少了。

为了解决这个问题,你还可以再想想,有没有别的表示方式?

通常当你用十进制记录一个非常大的数字时,你会怎么记录它?是不是会使用科学计数法?

类似的原理,你可以把二进制数分为两个部分,1.38所代表的小数和10^9所代表的指数,这也是计算机中所使用的浮点数表示方法。

例如,如果是32位数,将左边的第一位表示为符号位,符号位右边的8位表示指数位,最后剩下的23位表示小数位。具体换算时,需要使用一套专门的计算规则。

到目前为止,你已经只使用0和1这两个符号就表示出了平时所使用的各种数字。

电脑和手机上除了记录数字之外,还要用来记录各种文字。这又该如何做到?

方法很简单,想象一张字典表,左边是一个二进制数,右边是一个文字,将它们一一对应起来。

例如,用00000代表A,00001代表B,00010代表C,以此类推。这样一来你就可以用5位二进制数表示出所有的26个英文大写字母。如果你还想表示小写字母、标点符号或者中文汉字等等,只需要增加二进制数的位数即可。

当你想要使用上面的规则给你的好朋友说“你好”,计算机实际发送过去的就是0011 0101 0011 0110。

不过你的朋友可能会遇到一个问题,假如他并不知道上面这张编码表,他就不知道上面这串二进制数代表什么意思,这时在他的电脑上就会显示一些乱码。

为了解决这个问题,想要交流的不同人之间就需要使用相同的编码表。目前不同国家的组织已经制定出了各种不同的编码表。

例如,由美国制定的只包含英文字母、数字和一些标点符号的ASCII码、由中国制定包含简体中文及繁体中文的GBK编码,还有包含所有语言文字的UTF编码等。

你的电脑和手机显示文字时,除了需要知道用于表示文字的01符号,还需要知道它所使用的编码规则。

文字已经产生了,接下来可以开始考虑如何用0和1来表示图片。

如果你看过我写的Scratch 3 学习手册,使用过Scratch中的绘制工具,你就会知道,Scratch的舞台实际上是由120x90个小方格所组成。

如果你想在舞台上显示一个数字1,应该怎么做?是不是只需要让中间几列小方格显示黑色,其他的小方格显示白色就可以了?

接下来,将黑色的格子用0表示,白色的格子用1表示,整个舞台是不是就变成了由一堆0和1组成的二进制数。

例如,将舞台想象成为8x6格,下面这张图片就可以表示为11111111 11100111 11100111 11100111 11100111 11111111,其中的规则是从左至右,从上到下将所有的01符号拼接在一起。

现在每个格子只有0和1,它们只能表示黑白两种颜色。如果想要增加更多颜色,或者想要调整图片的饱和度、亮度、透明度怎么办

方法很简单,在每个格子中使用更多的数字表示即可。

例如,Scratch中就使用了3个0~100的数字分别代表颜色、饱和度和亮度。你可以计算一下,将它们转换成二进制数的话,需要使用多少位才行。

接下来是声音,它就是物体振动产生的声波,你只要用数字记录下一段时间内的振动频率,就可以将它表示出来。

如果你使用过Scratch中的音乐分类积木,你就知道还可以用数字来表示不同的音符、节拍和速度。

至于视频呢?它就类似Scratch中的动画效果,你只用把多张图片和声音的二进制串拼接在一起连续播放就可以了。

和文字一样,计算机中对于图片、声音和视频已经制定了很多不同的编码规则。对应到你的电脑上,就是那些不同后缀名的文件。它们全部都由0和1两种符号组成,再使用各自的编码规则。

现在你知道为什么不同格式的文件,只能用特定的软件才能打开了吗?

回到最开始的问题,计算机眼中的世界真的只有0和1吗?答案是不一定。

你可以回忆一下,在整篇文章中我们只做了两件事。第一,确定需要使用的符号;第二,为这些符号规定不同的编码规则来表示不同的东西。

例如,我在信息技术发展简史(3)提到的世界上第一台通用计算机ENIAC,使用的就是十进制。1958 年在苏联莫斯科国立大学建造了第一台三进制计算机 Сетунь。如果你将生物体看作是一台计算机的话,生物遗传密码DNA所使用的就是AGCT这四个符号所表示的四进制。

最后,再给你留两思考题。

  1. 现代计算机为什么最终选择使用0和1所表示的二进制,而不使用日常生活中使用的十进制?
  2. 在计算机中真的会有0和1这两个数字吗?如果不是,0和1具体所代表的又是什么?

0条留言

留言