这看起来或许有些奇怪,一本论述数据压缩的书居然以二进制数开头。还请读者多担待,因为数据压缩所做的无非就是尽可能减少表示特定数据集时所需的二进制位数量。为了进一步阐述这一概念以及它在数学上的影响,我们不妨在此花一点时间,确保每个人的理解程度一致。

现代数学建立在十进制计数系统之上。这里说的是现在的情况,我们相信未来某一天量子计算或巴比伦计数法会改变这一点。

有了这一计数系统,我们就可以用[0,1,2,3,4,5,6,7,8,9] 这10个数字来表示任何数值。上小学时,你可能已接触过数位的概念,比如193这个数从左到右包含3个数位,分别是百位、十位和个位,如下表所示。

实际上,193就等于1×100 + 9×10 + 3。一旦掌握了这个规则,你就会认识到可以一直这样数下去,数到任何数都可以。

后来,学了指数后,你知道可以用以10为底的指数去代替百位和十位,这样新的规律又出现了,如下表所示。

因此,下式成立:

因为每一列只能有一位数字,所以在9的基础上再加1会发生什么呢?从9再数一位,得到10(两位数)。因此,将0放在个位()列,并将1向左移一位,也就是移到(十位)列,该列表示的是十位,如下图所示。

如果接着往上数,我们会遇到)。当数到99时,再往上数,就需要进位继续左移,因此结果为

二进制计数系统的工作原理与十进制计数系统一样,唯一的区别是前者的基数为2,而后者的基数为10。因此,与十进制中每一列都表示为以10为底的指数()不同,在二进制中每一列都是以2为底的指数()。

此外,十进制中在进位之前有0~9这10个数字可用,而在二进制中只能使用0、1这两个数字。

因此,在二进制中计数,我们有“0”“1”,同时由于21已进位到了下一位,因此二进制中“2”表示为10,“3”表示为11,而“4”等于22,需要再进一位,因此表示为100,如下图所示。

1.将二进制转换为十进制

当你阅读本章前面的内容时,我们确信你的大脑已经将二进制数转换成了相应的十进制数,这是因为除非一直以来都使用二进制数,否则你还是会通过其对应的十进制数来理解二进制数。

让我们更明确一些,假定有二进制数1010,将它填到各数位的列中,如下表所示。

为了得到对应的十进制数,我们将数值为1的列对应的值加起来,通过上面的表格,得到下式:

因此,二进制数1010等于十进制数10。

通过上面的步骤,可以看到,将二进制数转换为十进制数很简单。反过来,将十进制数转换为二进制数则要稍微复杂一些。

2.将十进制转换为二进制

要将十进制数转换为相应的二进制数,一种简单的方法是用十进制数一直除以2,所得的余数为“1”或“0”,然后将所有这些余数串起来。

实际操作一次更便于理解。下面就用这种方法将十进制数294转换为相应的二进制数。

(1) 首先用294除以2,所得的商为147,余数为0。

(2)将步骤(1)中所得的商147继续除以2,此时商为73,余数为1。

(3)将步骤(2)中所得的商73继续除以2,得到相应的商和余数,重复这样的操作,直到所得的商等于0而余数等于1,由此得到下表。

需要注意的是,如果上述步骤中被除的十进制数是偶数,那么该十进制数将被2整除,余数为0;而如果该数是奇数,那么该数将不能被2整除,余数为1。

现在将所得的余数从右向左串起来(通过上表来看是从下往上串起来的),将最低有效位(least significant bit,LSB)放在最右边,最高有效位(most significant bit,MSB)放在最左边,由此得到100100110。

就这样,通过一直除以2这种将十进制转换为二进制数的技术,我们得到了最终的结果100100110,它就是与十进制数294对应的二进制数。

一通百通,一懂百懂

结果表明,这种除以基数的方法也可以将十进制数转换为其他进制数。在计算机科学领域,另外一种常用的基数是16,也称为十六进制数。由于没有哪个一位的数字符号能表示10以上的十进制数,因此我们用字母A来表示10,用B表示11,以此类推,用F表示15。读者不妨试一试将十进制数3053转换为十六进制:先除以16,再将所得余数从右向左串起来。友情提示:转换的结果可能会让人产生睡意。