什么是二进制

引言

我们从小就会数数。

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^0100, 10110^1101, 10210^2102, 10310^3103……

如在数字1394中：
“4” 位于个位上，代表4个10010^0100（一）
“9” 位于十位上，代表9个10110^1101（十）
“3” 位于百位上，代表3个10210^2102（百）
“1” 位于千位上，代表1个10310^3103（千）

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

二进制的道理与之相同。
二进制的每个数位，分别代表202^020, 212^121, 222^222, 232^323……

如在二进制数字1010中
第一位的 “0” 代表 0 个202^020
第二位的 “1” 代表 1 个212^121
第三位的 “0” 代表 0 个222^222
第四位的 “1” 代表 1 个232^323
全部加起来，就是0×20+1×21+0×22+1×23=100\times2^0+1\times2^1+0\times2^2+1\times2^3=100×20+1×21+0×22+1×23=10

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

实践

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

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

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

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

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

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

第三位 | 第二位 | 最低位 | 描述
0 | 1 | 1 | 原来的数 3
0 | 1 | 1+1 | 加 1
0 | 1+1 | 0 | 发现最低位到 2 了，于是将其归零，下一位加 1
0+1 | 0 | 0 | 下一位也到 2 了，再归零，再下一位，即第三位加 1
1 | 0 | 0 | 最终得到 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-00007F | 0xxxxxxx
000080-00007FF | 110xxxxx 10xxxxxx
000800-00FFFF | 1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF | 11110xxx 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=282×14=28个卡片
3 进制需要3×9=273\times9=273×9=27个卡片
5 进制需要5×6=305\times6=305×6=30个卡片
10 进制需要10×4=4010\times4=4010×4=40个卡片
16 进制需要16×4=6416\times4=6416×4=64个卡片

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

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

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