1.6 十六进制

在结束用二进制思考这个话题之前,我还要提一下另一个数字系统:十六进制。我们“正常的”数字系统是十进制系统,或者说以10为基数的系统。计算机使用的是二进制系统,即以2为基数的系统。十六进制系统以16为基数!十六进制(缩写为hex)系统也是一种位值系统,其中的每个位置都表示16的幂,每个位置的符号都可以是16个符号中的一个。

和所有的位值系统一样,最右边的位置仍是1的位置,其左边第一位是16的位置,然后是256(16×16)的位置,之后是4096(16×16×16)的位置,以此类推。非常简单!但是,每个位置可以放置的16个符号是哪些呢?通常,我们有表示数字0~9的10个符号。要表示其他值,还需要另外6个符号。我们可以随机选择一些符号,比如&、@和#,但是这些符号没有明显的顺序。相反,采用A、B、C、D、E和F(大小写均可)才是标准做法。在这个方案中,A代表10,B代表11,以此类推,直到F,它代表的是15。这样是对的,我们需要一些符号来表示从0到基数减1的数字。因此,其他6个符号是A~F。为了清晰起见,标准的做法是用前缀0x来表示十六进制。表1-5列出了16个十六进制符号,以及它们十进制和二进制的值。

表1-5 十六进制符号

当需要表示的值大于十进制的15或十六进制的0xF时会怎么样呢?和十进制一样,我们增加一位。0xF的后面是0x10,这就是十进制的16。然后是0x11、0x12、0x13,以此类推。现在看一下图1-4,便可以看到更大的十六进制数0x1A5。

图1-4给出了十六进制数0x1A5,它的十进制值是多少呢?最右边位置的值为5,旁边位置的权重为16,位置上有个A,A代表十进制的10,因此,中间位置为16×10=160。最左边位置的权重为256,位置上有个1,所以这个位置的值为256。总数值用十进制表示为5+160+256=421。

图1-4 按位值分解十六进制数0x1A5

为了强调这一点,这个例子展示了像A这样的新符号是如何根据其出现的位置而有不同的值的。0xA是十进制的10,0xA0则是十进制的160,因为A出现在16的位置上。

现在,你可能会说:“太棒了,但是这有什么用呢?”我很高兴你有这样的疑问。计算机不使用十六进制,大多数人也不使用。但是,十六进制对于那些要处理二进制数的人来说却是很有用的。

使用十六进制有助于克服处理二进制数的两个常见困难。首先,大多数人都不擅长阅读较长的0/1序列。之后,这些位要一起运行。对于人类而言,处理16个或更多的位很困难且容易出错。其次,尽管人类善于处理十进制数,但十进制和二进制之间的转换并不容易。对于大多数人来说,很难在看到一个十进制数后,就能很快说出该数用二进制表示时哪些位是1,哪些位是0。但是,将十六进制转换成二进制要简单得多。表1-6给出了2个16位二进制数及其对应的十六进制与十进制表示。注意,为了清晰起见,我在二进制数值中添加了空格。

表1-6 16位二进制数及其十六进制和十进制表示

先看表1-6中的例1。它的二进制表示是个明确的序列:前4位全是1,之后的8位全是0,最后的4位全是1。从十进制角度来看,这个序列是模糊的。从61455来看,完全不清楚哪些位是0,哪些位是1。而十六进制序列是二进制序列的镜像。第一个十六进制符号是F(即二进制中的1111),之后的两个十六进制符号是0,最后一个十六进制符号是F。

接着看例2,前3个4位组都是1000,最后一个4位组是0001。这在二进制中看着很简单,但在十进制中看着就很难了。十六进制提供了更清晰的表示,十六进制符号8对应于二进制的1000,十六进制符号1对应于0001!

我希望你能看出一种模式:二进制中每4位对应于十六进制中的1个符号。如果你还记得4位是半个字节的话,那么便可知道一个字节可以表示成两个十六进制符号。一个16位的二进制数可以用4个十六进制符号表示,一个32位的二进制数用8个十六进制的符号表示,以此类推。让我们以图1-5中的32位二进制数为例。

图1-5 每个十六进制符号映射为二进制中的4位

在图1-5中,我们可以按每次半字节的节奏来消化这个相当长的数字,这是用十进制表示的相同数字(2320695040)无法办到的。

由于二进制与十六进制之间的转换相对容易,因此许多工程师通常会同时使用它们,只在必要时才会转换成十进制。后续在有意义的情况下,本书将会使用十六进制。

尝试不经过转换成十进制的中间步骤,把二进制转换成十六进制。

练习1-4:将二进制转换成十六进制

把下列用二进制表示的数字转换成等价的十六进制数。如果可以的话,不要先转换成十进制。本题的目标是直接从二进制转换成十六进制。

10(二进制)=______(十六进制)

11110000(二进制)=______(十六进制)

一旦你掌握了将二进制转换成十六进制的方法,就尝试一下从十六进制转换成二进制。

练习1-5:将十六进制转换成二进制

把下列用十六进制表示的数字转换成等价的二进制数。如果可以的话,不要先转换成十进制。本题的目标是直接从十六进制转换成二进制。

1A(十六进制)=______(二进制)

C3A0(十六进制)=______(二进制)