如果您从事计算机方面的工作,或者是使用过计算机,你很有可能听过这样一种理念:计算机只是“一堆1和0”,这也是我在进入软件行业之前对计算机了解的少数事情之一。
刚开始,我并不完全理解这句话,直到我学会了编程后,我才真正理解这意味着什么。是的,计算机依靠 1 和 0 运行。它肯定比这复杂一些,但也没有复杂到我们无法理解!
事实上,计算机是一种称为二进制的数字系统,二进制数字系统基于一个简单的想法,即您可以只用两个数字来计数,而不是像我们在幼儿园学到的那样用 10 个数字来计数。
那么,如果二进制只有两个数字,那如果超过2怎么计数?
二进制计数
在我们熟悉的现代计数系统中,每个位置有十个可能的数字(0-9)。这就是为什么我们有时听到人们称我们的计数系统为十进制计数。
在二进制数字系统中,每个位置只有两个可能的数字(0-1),所以我们可以称之为二进制计数(有时简写为bin,表示二进制)。
可以看出,二进制和十进制计数方式上的主要区别就是每个位置可能出现的次数。
在上图下边的例子中,我们可以看到我们开始计数的方式与十进制相同。首先是0,然后是1。但是当我们到达数字2时,如何继续计数呢?
好吧,让我们看看在十进制中我们怎么做(图上部分所示)。当我们到达数字9时,我们会做什么?我们将最低位个位重置为0,并将十位增加到1。当我们遍历了 10-19 之间的所有可能性后,我们将个位重置为 0,并将十位增加为数字 2。我们这样做,直到达到 90-99 之间的数字,然后我们再添加一位:百位。
同样的逻辑也适用于二进制计数。从 0 数到 1 后,然后再往下数就是十进制数的2了,但是在二进制计数中,每个位置只能是0或者1这两个数字中的一个,因此为了表示数字 2,我们将第一位重置为 0,并在左侧添加一位数字1变成:10,然后继续往下数就是11(十进制的3),如果还要继续往下数就是十进制的4了,将第一位和第二位重置为 0,在左侧添加一位数字1变成:100;如果我们继续这样做,我们将看到二进制中的前 10 个数字如下所示:
0
1
10
11
100
101
110
111
1000
1001
以二进制书写
我们知道计算机只能识别二进制。但我们没有人会在键盘上输入二进制!可以看看您的键盘,除了数字之外,还有英文字母以及标点符号等。这让我们相信,二进制只是给计算机看的,我们人类输入进去的还是熟悉的0-0,a-z…等字符,那么这中间必然存在一个转换过程 !
这个过程就是编码:将我们输入到机器中的内容会被转换成二进制数字的过程,这个编码过程是通过几层抽象层来实现的,我们不会深入讨论所有这些抽象层。
虽然了解所有的层次并不重要,但我认为了解一点关于转换的工作原理还是有必要的。为了保持简单这里我们重点介绍如何将十进制数字(整数)转换为二进制。
还记得小学时我们都必须学习乘法表吗?到了初中时我们开始学习指数并意识到乘法表有多有用吗?好吧,准备再次重新认识这一点吧!过去一周,我一直在练习二进制的转换,然后我意识到学习二进制时最重要的事情就是复习 2 的幂。
十进制转换成二进制
要将一个十进制数转换为二进制数,我们要做的是将这个十进制数分解为 2 的幂。所以我们可以问自己:在不超过要转换的数字的情况下,2 的多少次幂最接近它,一旦找到这个数字,我们就从总数中减去它(2的这个数字的幂),然后重复此过程,直到剩下零。
在十进制中,有个位、十位、百位、千位等等。在二进制中,我们的位置将是:一、二、四、八、十六;换句话说,就是2的0次幂、2的1次幂、2的2次幂,等等,一旦我们将数字分解为 2 的幂,我们就需要将它们放在正确的位置,比如某个数包含了2^5次,那么其对应的二进制 2的5次幂这个位置一定是1, 即 xxx1
xxxxx
让我们看几个例子。首先,让我们尝试将十进制27转换成对应的二进制。
转换过程如下:在不超过27 的情况下,我们可以得到的最大 2 的幂是 16,即 2 的 4 次方(2 的 5 次方是 32,这太大了,因为它超过了我们的数字!),因此知道我们需要在2 的 4 次方”的位置上放置一个 1,现在得到 1xxxx,其它位现在还不知道,记为x,表示未知。
然后将 27 - 16 = 9这个数字分解为 2 的幂,可以得到在不超过9 的情况下,我们可以得到的最大 2 的幂是8(2 的 3 次方),因此继续在2 的 3 次方”的位置上再放置一个 1,现在得到 11xxx。
接下来继续将9 - 8 = 1这个数字分解为 2 的幂,可以得到在不超过1 的情况下,我们可以得到的最大 2 的幂是1(2 的 0 次方),因此继续在2 的 0次方”的位置上再放置一个 1,现在得到 11xx1。
现在 1-1=0,分解完毕,将11xx1的x替换为0,就是这样!十进制数字 27 可以从十进制转换为二进制:11011。
好的,再举一个例子。这次我们尝试一个大的数字——114。
在不超过114 的情况下,我们可以得到的最大 2 的幂是 64,即 2 的 6 次方(2 的 7 次方是 128,这太大了,因为它超过了我们的数字!),因此知道我们需要在2 的 6 次方”的位置上放置一个 1。
让我们继续将 114 - 64 = 50这个数字分解为 2 的幂,可以得到在不超过50 的情况下,我们可以得到的最大 2 的幂是32(2 的 5 次方),因此继续在2 的 5 次方”的位置上放置一个 1。
根据图示,继续分解下去,最终我们就会得到十进制数字114对应的二进制数为:1110010。
如果我们做了足够多的二进制转换,我们会注意到一个规律:
十进制的偶数在转换成二进制时总是以0结尾。相反,十进制的奇数在写成二进制时总是以1结尾。
二进制转换为十进制
当我们将十进制转换为二进制时,我们会将数字分解为 2 的幂,
基于该逻辑,如果我们想将二进制转换为十进制,我们将做完全相反的事情。也就是说:我们将二进制的每一位乘以 2 的对应次幂,然后相加,其结果就是对应的十进制。
例如我们将二进制101011转换为十进制:
首先,我们来看看每个位置上有什么,并记住这个位置与 2 的哪个幂相关。我们可以从左到右开始:我们看到 2 的 5 次幂 位置有一个 1,因此这里得到一个数 1 * 2^5 = 32;
然后继续。2 的 4 次方位(我们也可以称之为 16 位)有一个零,所以我们不是将它乘以 1,而是将它乘以 0,这次得到的数是0;
这样一直遍历到2的0次方位置,得到一组数:32、8、2 和 1(相当于 2 的 5 次方、2 的 3 次方、2 的 1 次方、2 的 0 次方)。所有这些数字相加,得到十进制转换结果 101011:即数字43。
再举一个简单的例子——这次,我们尝试一个较小的数字。以下是将10100转换为十进制的过程:
这个更容易理解!我们甚至可以在脑中完成(取决于我们对 2 的幂的了解程度)。我们知道我们要将 2 的 4 次方和 2 的 2 次方相加其结果是20。就是这样!10100 等于十进制中的20。很简单!
计算机如何解释二进制?
好了,数学就讲到这里。这跟计算机有什么关系?
我们已经知道计算机可以解释二进制。但我们可能没有意识到,计算机的组成部分——开关和电路——实际上是二进制的表示。
一台计算机有数十亿个(超小型)数字电路,这些数字电路非常简单。都是由开关组成,一个开关只能有两种状态:开或关。这非常适合用二进制来表示:开是1,关是0。
更酷的是,计算机中的所有东西(以及计算机科学中的所有东西)在最基本的层面上,都是基于这种开/关的模式。
那么计算机如何将复杂的事物(例如这篇博客文章)用0和1表示了?
二进制的每一位称为一个比特(bit),一个比特只能由0或1组成, 8 比特(8 位数字)串在一起形成一个字节(byte),字节被认为是计算机内存的一个基本单位。
我认为字节特别有趣,因为一个字节可以表示256 种不同的组合。(还记得 2 的幂吗?2 的 8 次方是 256。)如果你有两个字节呢?两个字节意味着 16 位(二进制数字),这意味着你可以表示 65,536 种不同的组合(2 的 16 次方)!仅仅使用2个字节就能表示这么多不同的排列!
比特(bit)是字节的组成部分,非常基础,值得我们去理解。bit之所以重要,是因为不同的计算机一次可以处理的bit数不同。例如,一个8位机器一次可以处理8个bit数据。而 16 位机器每次将一次处理16个bit的数据。计算机中一次处理的比特数称为计算机字长
。
现在大多数计算机现在有32位或64位的字长。现在你知道这意味着什么了:你的机器一次能处理32或64个bit的数据。
让我们以一个单词中的一个字符为例。该字符需要 8 位(或 1 个字节)来表示。如果是更长的内容,例如一页大约1000单字的文本,那将需要更多的字节!
做个懂二进制的程序员
如今很少有程序员会思考二进制。尽管我们内心深处知道它很重要,值得学习,但又觉得它太过复杂,没有必要去思考。
但是,如果您回想一下计算机给我们人类带来了多大的进步和改变,这真是令人瞠目结舌。
而这一切的核心就是二进制,所以,如果你对计算机感兴趣或从事与计算机相关的工作,了解一点二进制的基础知识是很有必要的。
更多高质量原创技术文章可扫码关注公众号:“非科班大厂码农”