banner
寒寒

寒寒

misskey
github

什么是二进制

什么是二进制#

引言#

我们从小就会数数。

1,2,3,4,5,6,7,8,9,10,11,12 ……
任何一个智力正常的人都能无穷无尽地数下去。

可是你有没有想过,数字难道就只能是这样的吗?
接下来,我们换一种数数方法。
1,10,11,100,101,110,111,1000,1001,1010,1011,1100……

你可能有点摸不着头脑,但这就是刚刚 1~12 在二进制里的表示。
看完这篇文章,我相信你能彻底理解。

这篇文章从数制写起,讲解了二进制是什么,为什么要用二进制,还讲解了由 1 和 0 构成的二进制数是怎么变成我们计算机中的文本、图片、视频的。文章挺长,但耐心读完,我相信你能有所收获。

数字#

绝大多数人生来有两双手,每只手有五个手指
当我们还在幼儿时代时,我们就会借助手指来数数了。

人大多数情况下只有十根手指,那么如果想表示大于十的数,该怎么办?
你大概会说:“这不是很简单嘛,可以用数字啊”
古人也是一样的想法,因此创造了各种符号用来表示 “数”

现今,我们最常用的是阿拉伯数字。

进制与数字#

进制#

小学老师教过我们,阿拉伯数字是 “满十进一” 的,即每当数到了 10,就将当前的一位归零,将下一位加上一。
这就是进制
满几进一,就是几进制。

比如阿拉伯数字中,当从 0 数到 9 后,下一个数字就不再用新的数字表示,而是将十位写上 1,个位写上 0,也就是 10,这便是十进制,也是绝大部分人日常使用的进制。

而二进制就是 “满二进一”,即每当数到了 2,就将当前的一位归零,将下一位加上一。 因此,类似于十进制有 10 个数字,二进制只有两个数字,0 和 1

“位” 的意义#

十进制中,对于一个数字中的单个数位,我们有 “个位”、“十位”、“百位”、“千位” 之称。
其中每个数位,分别代表有多少个10010^0, 10110^1, 10210^2, 10310^3……

如在数字1394中:
“4” 位于个位上,代表410010^0(一)
“9” 位于十位上,代表910110^1(十)
“3” 位于百位上,代表310210^2(百)
“1” 位于千位上,代表110310^3(千)

合起来,就是1×1000+3×100+9×10+4×1=13941\times1000+3\times100+9\times10+4\times1=1394

二进制的道理与之相同。
二进制的每个数位,分别代表202^0, 212^1, 222^2, 232^3……

如在二进制数字1010
第一位的 “0” 代表 0202^0
第二位的 “1” 代表 1212^1
第三位的 “0” 代表 0222^2
第四位的 “1” 代表 1232^3
全部加起来,就是0×20+1×21+0×22+1×23=100\times2^0+1\times2^1+0\times2^2+1\times2^3=10

在二进制的部分,你可能注意到我没有说 “个位”,“十位”,而是说 **“第一位”,“第二位”**,这是因为 “个位”、“十位” 的叫法本身就是对于十进制而言的,因此无法被用于描述二进制的数位,后同。

实践#

现在让我们来用十进制和二进制从 1 开始数数,巩固一下刚刚的知识吧。

  1. 首先是 1,这个数字在十进制和二进制都是一样的,略过。

  2. 接下来,到了十进制的 2,刚刚我们讲过,二进制 “满二进一”,因此我们应该将最低位归零,并在下一位加一,也就是10

  3. 十进制的 3 呢?很简单,你应该也能想明白,应该是 11。

  4. 到了十进制的 4,很明显,再加 1 的话最低位又到了 2。因此将最低为归零,并将下一位加一。可是下一位本来就是 1 啊,那怎么办?很显然,下一位也应该归零,再将第三位加一,最终得到100

这是从 3 数到 4 的整个流程:

第三位第二位最低位描述
011原来的数 3
011+1加 1
01+10发现最低位到 2 了,于是将其归零,下一位加 1
0+100下一位也到 2 了,再归零,再下一位,即第三位加 1
100最终得到 100

总结#

二进制其实没有那么难,核心思想就「满二进一」,只要懂了这个,你也能向平时数数一样,轻松地用二进制数数。

为什么要用二进制#

我相信,看我文章的,大概都对电脑有一定了解吧。

一种简单的说法是,计算机的处理器是电路构成的,而电路中,通电(或高电压,开启)表示 1,不通电(或低电压,关闭)表示 0,实现起来很简单。

并且,在逻辑中,“真”、“假” 两种状态也正好可以用 1 和 0 来表示。

二进制在计算机中的具体实现#

引言#

在计算机中,所有的文字、图片、视屏、网页、文档、软件在计算机眼里,都只是由 0 和 1 构成的二进制数据。

字节与比特#

计算机中的二进制数据通常以 8 位二级制数来分割,因此8个二进制数字被称为 1 个字节 ,1 个二进制数字叫 1比特

编码#

当我们在处理文本、音频、图像等信息时,计算机需要将这些信息转换成二进制数字进行处理。这个过程称为编码

文字编码#

简述#

说起文本在二进制中的表示方法,就不得不提到文字编码。文字编码是二进制与文字的对应关系,它可以让计算机把某个二进制数字转换为字符,或将字符转换为二进制数。文字编码的核心思想并不复杂,就是一个类似于字典的表,计算机在转换过程中,逐个字符查表即可。

常用的文字编码有ASCII、GBK、GB2312、Unicode等。

文字编码的历史 & 常见的文字编码#

ASCII#

计算机是美国人发明的,他们发明电脑时,只想过把自己的 26 个英文字母装进表中,大写和小写字母,再加上数字和标点符号(其实还有一些控制字符,比如换行、回车、制表符等),7 位二进制(十进制最大 127)足够了,又预留了一位,刚好 1 字节(8 位)。多出来的一位,后来被欧洲的那些带了变音符号的字母占去了。这就是ASCII(美国信息交换标准代码)。

中文编码#

计算机传到了中国,中国人一看,1 字节哪够装汉字啊,于是大陆整出了装简体字的GB2312,使用两个字节表达汉字,包括 6763 个常用汉字(包括一级汉字 3755 个,二级汉字 3008 个)。台湾这边呢,整出了装繁体字的Big5(大五码),共收录 13060 个汉字,同样也用两个字节表示一个汉字。后来大陆还推出过 GB2312 的 “高级版”GBK,它在 GB2312 的标准上多加了不少生僻字和其它字符,总计有两万多个汉字,但同样以双字节存储。

Unicode#

后来,中国有中国的编码,美国有美国的编码,日本有日本的编码,欧洲有欧洲的编码…… 终于,计算机界的大牛一拍大腿,搞出了Unicode。Unicode 是 uni 前缀(表示 “一”“统一”)和 code(表示编码)组合而成的词。这表示 Unicode 的核心理念是包含世界上所有语言的字符,统一所有的编码,最终成为一个世界通用的编码。幸运的是,它做到了。截至 2021.09.14 发布的Unicode14.0标准,Unicode 总共包含 144967 个字符,囊括了你见过的没见过的知道的不知道的有人用的没人用的…… 各种语言的字符,当然还包括 emoji。

UTF-8(可变长度编码)#

之前我们说过,中文编码大多是两个字节,是因为两个字节最多可以装下 65535 个字符,无论是 GB2312 的 6763 个还是 GBK 的两万多个都绰绰有余,但是到了 Unicode 时代,理论上是需要四个字节表示的,但是有聪明人想出了可变长度编码这个东西。它可以根据不同的字符来保存不同长度的数据,并且能保证计算机能准确分割。比如英文字符用 1 字节,中文用 3 字节,emoji 用 4 字节。(这里中文多出一个字节是因为可变长度编码本身需要浪费一定空间,但是比所有字符均用 4 字节好得多)

如果你想知道可变长度编码具体是如何实现的,请看下表。

Unicode 编码(十六进制)UTF-8 字节流(二进制)
000000-00007F0xxxxxxx
000080-00007FF110xxxxx 10xxxxxx
000800-00FFFF1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

表的左边是文字的 Unicode 十六进制编码,右边是二进制数据,其中 x 表示有实际用处的数据,其余部分因可变长度编码的实现机制占用。

之前提到,可变长度编码的用处是即使每个字符用不同长度的二进制数据保存,计算机仍然能准确地将一大串二进制数字中分割出每个字符。那么是怎么做到的呢?

很简单,我们看表的右边,每一个 Unicode 编码范围对应的二进制数据的开头,要么是 0,要么是一堆 1 加一个 0。计算机仍按照字节读取,每个字节的开头有几个 1,这个字符就占几个字节。

正是可变长度编码的出现,才将 Unicode 的最大弱点 — 占用空间大的问题消灭,使得 Unicode 得以在全世界范围内流行,成为计算机界的 “理想编码”。

图片、视频和音频的编码#

图片编码#

图片的编码方式主要有两种:无损编码和有损编码。无损编码方式可以保留图片的全部信息,但文件通常较大,常用的无损编码方式有 GIF 和 PNG。有损编码方式则通过牺牲部分信息来达到压缩文件大小的目的,常用的有损编码方式有 JPEG。

在计算机中,图片以像素阵列的形式存储。每个像素都是由红、绿、蓝三个颜色通道的亮度值组成的。在 GIF 和 PNG 这两种无损编码方式中,采用的是基于像素的编码方式,即每个像素的值都单独进行编码。而在 JPEG 这种有损编码方式中,采用的是基于变换的编码方式,即将像素转换为频域上的变换系数进行编码。

视频编码#

视频编码方式通常也采用有损编码方式,以便压缩视频文件的大小。常用的视频编码标准有 MPEG-1、MPEG-2、MPEG-4、H.264、H.265 等。其中,MPEG-2 是用于 DVD 的标准,MPEG-4 则广泛应用于各种流媒体应用。

视频编码的过程主要包括两个步骤:空间预测和变换编码。在空间预测中,每一帧的像素值都是由其前一帧像素值进行预测得到的。这样可以大大减少每一帧需要编码的信息量。而在变换编码中,则采用了和 JPEG 类似的基于变换的编码方式,将每一帧的像素值转换为频域上的变换系数进行编码。

音频编码#

音频编码方式通常也采用有损编码方式,以便压缩音频文件的大小。常用的音频编码标准有 MP3、AAC、WMA 等。其中,MP3 是最为流行的音频编码格式之一,它的压缩率可以达到 10:1 或者更高。

音频编码的过程主要包括两个步骤:时频变换和熵编码。在时频变换中,将音频信号转换到时域和频域上,以便更好地压缩信号。而在熵编码中,则根据信号的统计特征,采用更有效率的编码方式对信号进行编码。

拓展阅读#

其它进制的计算机#

其实,在计算机被发明的初期,也有十进制、三进制的计算机。

比如世界上第一台通用计算机 ENIAC 就是十进制。

而前苏联还曾造过一台三进制计算机Сетунь,它在不同的室温下都表现出惊人的可靠性和稳定性,生产和维护也比同期其它计算机要容易得多。但后来…… 苏联官僚对这个经济计划外的科幻产物持否定的态度且勒令其停产。 而此时,对Сетунь的订单却如雪片般从各方飞来,但 30 到 50 台的年产量远不足以应付市场需求。

很快,计划合作生产Сетунь的工厂倒闭了。1965 年,Сетунь停产了。取而代之的是一种二进制计算机,但价格却贵出 2.5 倍。

最终,这个很有潜力的计算机被扼杀了……

为什么用三进制#

其实,理论上 e 进制是存储效率最高的进制,但是 e 毕竟是一个无理数,不太好实现,而 3 最接近 e,因此用了三进制。

至于数学上的证明…… 略有些复杂,你若感兴趣可以看下一节。

我们只需要知道,三进制能用最少的存储空间保存更多的数据。

进制效率的详解#

本节中,对于 m 进制数 x,我们表示为 x (m)

我们先举一个例子。

假设我们要用 2、3、5、10、16 进制表示十进制 0-9999 的 10000 个数字,每个数制需要多少数位?

因为 10011100001111 (2)=9999 (10)
所以2进制需要14个数位。

因为 111201100 (3)=9999 (10)
所以3进制需要9个数位。

因为 304444 (5)=9999 (10)
所以5进制需要6个数位。

因为 9999 (10)=9999 (10)
所以10进制需要4个数位。

因为 270F (16)=9999 (10)
所以16进制需要4个数位。

假设,现在要用卡片来表示这些数,每个数制各需要多少卡片?

如:5 进制中有 0,1,2,3,4 五个数字,那么为了表示 1 位五进制数,我们需要准备 5 个卡片,也就是 1 位 n 进制数需要 n 个卡片

我们进行简单的乘法即可得知:

2 进制需要2×14=282\times14=28个卡片
3 进制需要3×9=273\times9=27个卡片
5 进制需要5×6=305\times6=30个卡片
10 进制需要10×4=4010\times4=40个卡片
16 进制需要16×4=6416\times4=64个卡片

当然,这个过程中出现了「资源浪费」,也就是部分卡片实际可以表达的数比我们规定的上限 9999 (10) 多。

那么,为了准确计算 x 进制表示 n 个数时需要用到多少卡片,我们需要用它表示 n 个数时的「理论位数」,乘以单个数位需要用的卡片数量 x。

什么是「理论位数」?之前的例子中,我们说 3 进制表达 9999 (10) 需要 9 个数位,这是因为log399998.3835log_{3}9999\approx8.3835,向上取整得到 9;而 5 进制要 6 个数位是因为log599995.7226log_{5}9999\approx5.7226,向上取整得到 6。而这个向上取整的过程,就是之前提到的「资源浪费」。而 5.7726、8.3835(近似值)则是我们所说的「理论位数」。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。