字节与十六进制

字节

纵观整个电路的脉络,每8个比特流为一组,如潺潺细流般在器件与器件之间流动。这8个比特流是加法器,锁存器也是数据选择器的输入形式,同时也是这些路件单元的输出形式。这9个比特流可以用开关的不同状态祝贺所定义,而且可以用灯泡的亮灭来显示。这样以来,这些电路种数据路径(Data Path)的位宽(bits wide)就是8.

为什么将它定义为“8”位呢?

因为每次使用8位位宽时,一切工作都显得非常方便——一种优雅的比特化(biteful)的比特流。十二章中计时器选8位时,正好时钟一个正跳变,二进制编码加1.加法器的为狂恰好也是8位。8比特代表一个字节(byte)。

字节这个词最早起源于1956年前后,由IBM公司提出。最早的拼写方式是bite,但是为了避免与bit混淆用y代替了i。曾几何时,字节仅表示某一数据路径上的位数,直到20世纪60年代中叶,在IBM的60系统的发展下(一种大规模复杂的商用计算机),字节这个词逐渐开始用来表示一组8比特数据。

由于有8位,一个字节的取值范围为00000000到11111111.相应地,它可以表示称为0~255之间的正整数,如果将一个数的补码作为其相应的负数,那么一个字节可以表示在-128~127范围内的正、负整数。一个给定的字节可以代表2^8,即256种不同事物中的一个。

让我们再来看看“8”这个数字,当8作为比特流的一种尺度,它的确表现出了非常完美的特质。字节在很多方面都比单独的比特更胜一筹。IBM采用字节有一个很重要的原因,就是这样以来数字就可以按照BCD(第23章将会讲述)方便地保存。在本章随后的讲述中,我们会发现凑巧的是:全世界大部分的书面语言(除了中文,日文以及韩文中使用的象形文字体系)的基本字符都少于256,所以字节是一种理想的保存文本的手段。字节同样适合表示黑白图像的灰度值,这是由于肉眼能区分的灰度约为256种。当一个字节无法表示所有信息(如刚提到的中文,日文以及韩文中使用的象形文字体系等),我们只需要采用两个字节——即2的16次方也就是65536个不同的物体——这也是一种很好的解决方案。

字节的一半——即4比特——我们称之为半字节(nibble,也可拼写成nybble),在计算机这个领域,它并不像字节那样经常使用。

十六进制

八进制数和二进制数之间的转换简洁方便,只要记住0~7这8个数字所对应的3位(log8=3)二进制数即可。下面这张表就表示了这种对应关系。

二进制数 八进制数
000 0
001 1
010 2
011 3
100 4
101 5
110 6
111 7

假如要把一个二进制数(如10110110)转换为8进制,可以从最右边的数字开始,每3比特看作一组,这样每组便对应着一个八进制数:

10110110这个字节很容易就表示为八进制数266.这个方法简洁明了,八进制来用表示字节不失为一个好方法。但还是有那么一点美中不足。

字节可以表示的二进制数的范围为00000000~11111111,如果采用八进制表示,那么相对应的范围也随之变成了000~377.仔细分析一下先前的理智,我们从右到左把3位二进制数对应于中间以及最靠右的八进制数,而最靠左的八进制数却是由二进制数对应的。如果我们将16位二进制数直接表示为八进制会得到如下结果:

如果我们把这个16位二进制数平分为两个字节将其分别表示为八进制数会得到如下所示的不同结果:

为了使多字节值能和分开表示的单字节取得一致,我们需要一种可以等分单个字节的系统,按照这种思想,我们可以把每个字节等分成4组,每组2bit(log4=2, 基于4的计数系统);还可以等分为2组,每组4bit(log16=4,基于16的计数系统)。

基于16的计数系统(Base 16),对于我们而言是一种全新的系统。基于16的计数系统也称为十六进制(hexadecimal)。《微软出版物风格与技术手册》中明确说明“请勿将十六进制缩写为hex”,但包括我在内的绝大多数人还总是在不经意间使用这个缩写。

两个十六进制数可以完整地代表一个字节。这也意味着一个十六进制数恰好由4位二进制数组成,即半字节。下面这张表描述了如何在二进制、十六进制、十进制之间的进行转换。

这样一来,字节10110110就可以表示为十六进制的B6.

可以用一种更加简洁实用的方法,那就是用小写的h紧跟在数字后边表示这个数是以十六进制表示的,就像这样:

B6h

通过分析可以得到十六进制数的每一位代表16的不同整数幂的倍数,如下图所示。

十六进制数9A48Ch,可表示为如下形式:

这个数用16的乘方表示可以写为:

运算的最后结果是631948.这就是一个十六进制转换成为十进制数的完整过程。

下面这个模版,帮助我们把4位十六进制转换为十进制。

十进制数转换为十六进制数通常涉及出发运算。下面给出一个十进制向十六进制转换的模版。

使用时首先把十进制写到左上角的方框里。这个方框代表着第一个被除数,然后处以第一个除数4096,得到的商放到被除数所对应的下面的方框里,而将余数放到被除数右边的方框里。这时将余数作为新的被除数去除以256.利用这个规则,通过反复迭代就可以得到最终结果。

下面这幅图向我们展示了十进制数31148转换为十六进制数的过程。

显而易见,十进制数的10和12代表者十六进制中的A和C,计算得到的最后结果就是79ACh。

还有一种转换小于65535的十六进制数的方法,首先我们把元素通过除以256的方式将其分为两个字节。接下来对于每个字节,再分别除以16.下图是运算过程使用到的模版。

我们采用自顶向下的方式。每一次出发完成后,就将其得到的商放入余数左下方的方框里,而余数进入右边的方框里。下图举例说明了十六进制数51966的转换过程。

最后我们得到了四个1位的十六进制数字,其十进制值分别是12,10,15和14,转换过来就是CAFE,无论怎么看它都像一个单词,我想应该没人愿意点一杯叫做51966的东西,然后把它当作咖啡喝下去吧!

对于每种计数系统,我们都可以描绘出相应的操作运算表,下面是十六进制的加法运算表。

使用这张表可以方便地仿照一般的加法运算来对十六进制数进行加运算,如下所示:

第13章的我们讨论过可以用一个2的补数来表示与其相对应的负数。如果我们处理的是带符号的8位二进制数,那么所有负数的最高位都为1.同理,在十六进制系统中,最高位为8,9,A,B,C,D,E或F的两位带符号数都是负数,因为这些十六进制数对应的二进制数的最高位为1.例如99h可以表示无符号的十进制数153,也可以表示十进制的-103.

Loading Disqus comments...
Table of Contents