2.1 计算机中数据的表示

计算机和其他数字设备要存储文字、声音、视频等多种数据,在存储的时候都是将这些数据转换为简单的电脉冲,并以0和1的形式存储。本节通过阐述数据在计算机中的表示方式,使读者了解数据的本质。

2.1.1 进位计数制

计数制是指用一组固定的数码和一套统一的规则表示数值的方法。按进位的原则进行计数称为进位计数制。

日常生活中常用的是十进制。此外,还有六十进制,如60秒等于1分钟,60分钟等于1小时;十二进制,如一年有12个月等。计算机中常用的是二进制、八进制、十六进制。表2-1所示为十进制、二进制、八进制、十六进制数码的表示方法。

进位计数制中表示一位数所能使用的数码符号个数称为基数。例如十进制数有0~9共10个数码,基数为10,逢10进1。

任何一个数,不同数位的数码表示的值的大小不同。例如,十进制中, 323.4可以表示为

323.4=3×(10)2+2×(10)1+3×(10)0+4×(10)-1

百位上的“3”表示300,个位上的“3”表示3。

每个数位的数码代表的数值,等于数码乘以一个固定数值,这个数值称为位权或权。各种进位制中位权均等于基数的若干次幂。因此,任何一种进位计数制表示的数都可以拆分为多项式的和。

1.十进制

十进制中,K表示0~9的10个数码中的任意一个数码,则任何一个数(N)可以表示为:

N=±[Kn-1×(10)n-1+Kn-2×(10)n-2+…+K0×(10)0+K-1×(10)-1+K-2×(10)-2+…]

2.二进制

计算机中信息的存储和处理都采用二进制。二进制数只有0、1两个数码,基数为2,逢2进1。为了便于区分,在二进制数后加“B”,表示数为二进制数。例如:

1101.1B=(1101.1)2=1×23+1×22+0×21+1×20+1×2-1=(13.5)10

表2-1 十进制、二进制、八进制、十六进制的数码表示方法

3.八进制

八进制有0~7共8个数码,基数为8,逢8进1。为了便于区分,在八进制数后加“O”,表示数为八进制数。例如:

127.5O=(127.5)8=1×82+2×81+7×80+5×8-1=(87.625)10

4.十六进制

十六进制有0~9、A、B、C、D、E、F共16个数码,基数为16,逢16进1,用A~F表示十进制中10~15的6种状态。为了便于区分,在十六进制数后加“H”,表示数为十六进制数。例如:

BE23.8H=(BE23.8)16=11×163+14×162+2×161+3×160+8×16-1=(48 675.5)10

综上所述,每种进制都有固定基数R,其数码为0、1、…、R-1。每一种进制都逢R进1。若用K表示不同数位的数码,则任何一种进制的数均可以表示为

(N)R=±[Kn-1×(R)n-1+Kn-2×(R)n-2+…+K0×(R)0+K-1×(R)-1+K-2×(R)-2+…]

2.1.2 不同进制数的转换

计算机中使用二进制,而现实生活一般采用十进制,因此经常需要在不同进制间相互转换。

1.不同进制数转换为十进制数

在2.1.1节中提到任何一种进制中的数均可以表示为

(N)R=±[Kn-1×(R)n-1+Kn-2×(R)n-2+…+K0×(R)0+K-1×(R)-1+K-2×(R)-2+…]

这恰恰是把任何进制的数转换为十进制数的方法,即用每个位置上的数码乘以相应的位权,然后求和。公式计算的结果就是对应的十进制数值。

【例2.1】 将二进制数(110010100111.1)2、八进制数(6 247.4)8、十六进制数(CA7.8)16转换为对应的十进制数。

(110010100111.1)2=1×211+1×210+0×29+0×28+1×27+0×26+1×25+0×24+0×23+1× 22+1×21+1×20+1×2-1=(3 239.5)10

(6 247.4)8=6×83+2×82+4×81+7×80+4×8-1=(3 239.5)10

(CA7.8)16=12×162+10×161+7×160+8×16-1=(3 239.5)10

2.十进制数转换为二进制、八进制、十六进制数

十进制数转换为对应的二进制、八进制、十六进制数,其整数部分和小数部分的转换方法不同。

(1)整数部分转换规则。将十进制数的整数部分转换为R进制数,通常采用“除R取余法”,即用十进制整数除以R取余数,将商反复除以R,直至商为零。

得到的第一个余数为最低位,最后一个余数为最高位,将所得余数从高位到低位依次排列,就是对应R进制数。

例如,把十进制数转换为二进制整数采用“除2取余法”,把十进制数转换为八进制或十六进制整数采用“除8取余法”或“除16取余法”。

【例2.2】 将十进制整数(167)10转换为对应的二进制、八进制、十六进制数。

(167)10=(10100111)2

(167)10=(247)8

(167)10=(A7)16

(167)10=(10100111)2=(247)8=(A7)16

(2)小数部分的转换规则。将十进制数的小数部分转换为R进制数,通常采用“乘R取整法”,即将十进制小数乘以R,取乘积的整数部分,然后用乘积的小数部分继续乘以R,直至最后一次的乘积为1.00…0或达到要求的精确度为止。

得到的第一个整数部分为最高位,最后一个整数部分为最低位,将所有整数从高位到低位依次排列,作为小数部分,就是对应R进制数。

有些十进制小数部分,如0.333,经过多次乘以R后,小数部分可能仍然不为0,或者可能永远都不为0,此时,根据精度的需要,可以进行小数点后位数的截取。

【例2.3】 将十进制小数(0.687 5)10转换为对应的二进制、八进制、十六进制数。

(0.687 5)10=(0.101 1)2

(0.6875)10=(0.54)8

(0.687 5)10=(0.B)16

(0.687 5)10=(0.101 1)2=(0.54)8=(0.B)16

3.二进制、八进制、十六进制数之间的转换

二进制、八进制、十六进制数之间的转换可以借助十进制数完成,也可以通过简单的方法直接转换。

如表2-1所示,每3位二进制数对应一位八进制数,每4位二进制数对应一位十六进制数。因此,将二进制数转换为八进制数的方法是,从小数点开始向两边,每3位二进制数转换成一位八进制数,数的开始和结尾部分不足3位的均补0。

将二进制数转换为十六进制数,则将每4位二进制数转换成一位十六进制数,其余同上。

【例2.4】 将二进制数(10100111.1011)2转换成八进制、十六进制数。

相应地,若想把八进制、十六进制数转换为二进制数,只需要把数值的每一位转换为对应的3位、4位二进制数即可。形成的二进制数,可省略开头和结尾处的零。

【例2.5】 将(367.45) 8、(E7B2.C8) 16转换为二进制数。

2.1.3 二进制数的算术运算与逻辑运算

目前,计算机中的数据均使用二进制进行存储和计算,在进行二进制算术运算时其运算规则与十进制相似,只是进位和借位的规则略不相同。二进制中其基数为2,因此在计算时采用逢二进一和借一当二的规则。

1.二进制数的算术运算

(1)加法运算。根据“逢二进一”的规则,二进制加法的运算法则为:

0+0=0

0+1=1+0=1

1+1=10(进位为1)

【例2.6】 计算(1001)2+(1011)2的结果。

(1001)2+(1011)2=(10100)2

(2)减法运算。根据“借一当二”的规则,二进制减法的运算法则为:

0-0=0

1-1=0

1-0=1

10-1=1(借位为1)

【例2.7】 计算(1101)2-(1011)2的结果。

(1101)2-(1011)2=(10)2

(3)乘法运算。二进制乘法与十进制数乘法规则非常接近。但由于二进制数只有0或1两种可能的乘数位,因此二进制乘法更为简单。二进制数乘法的法则为:

0×0=0

0×1=1×0=0

1×1=1

在运算时,由低位到高位,用乘数的每一位去乘以被乘数,若乘数的某一位为1,则该次部分积为被乘数;若乘数的某一位为0,则该次部分积为0。某次乘积的最低位必须和本位乘数对齐,所有乘积相加的结果则为相乘得到的最终结果。

【例2.8】 计算(101)2×(110)2的结果。

(101)2×(110)2=(11110)2

2.二进制数的逻辑运算

将逻辑变量之间的运算称为逻辑运算。二进制数1和0在逻辑上可以代表“真”与“假”、“是”与“否”、“有”与“无”等。这种具有逻辑属性的变量就称为逻辑变量。计算机的逻辑运算与算术运算的主要区别是:逻辑运算是按位进行的,位与位之间不像加减运算那样有进位或借位的联系。

二进制数的逻辑运算主要包括逻辑加法(“或”运算)、逻辑乘法(“与”运算)、逻辑否定(“非”运算)和逻辑“异或”运算。

(1)逻辑“或”运算。又称为逻辑加法,可用符号“+”或“∨”来表示。逻辑“或”运算的规则为:

0+0=0或0∨0=0

0+1=1或0∨1=1

1+0=1或1∨0=1

1+1=1或1∨1=1

在逻辑“或”运算中,只要两个运算数有一个为1,则结果必为1。只有当两个运算数均为0的时候,其结果才为0。要注意区别与算术运算中加法的区别。

(2)逻辑“与”运算。又称为逻辑乘,常用符号“×”或“· ”或“∧”表示。逻辑“与”运算的规则为:

0×1=0或0·1=0或0∧1=0

1×0=0或1·0=0或1∧0=0

1×1=1或1·1=1或1∧1=1

在逻辑“与”运算中,只要两个运算数有一个为0,则结果必为0。只有当两个运算数均为1的时候,其结果才为1。要注意区别与算术运算中乘法的区别。

(3)逻辑“非”运算。又称为逻辑否定,实际上是将原逻辑变量的状态求反,逻辑“非”运算的规则为:

在数字的上方加一横线表示“非”。数值为0时,逻辑“非”运算的结果为1。数值为1时,逻辑“非”运算的结果为0。

(4)逻辑“异或”运算。常用符号“⊕”或“∀”表示,逻辑“异或”运算的规则为:

0⊕0=0 或 0∀0=0

0⊕1=1 或 0∀1=1

1⊕0=1 或 1∀0=1

1⊕1=0 或 1∀1=0

在逻辑“异或”运算中,两个运算数的值相同时,逻辑“异或”运算的结果为0。当两个运算数的值相异时,逻辑“异或”运算的结果为1。

2.1.4 信息的数字化编码

信息是音讯、消息、通信系统传输和处理的对象,泛指人类社会传播的一切内容。信息在人类生产、生活中起着极为重要的作用,信息的分类如图2-1所示。

要使各种信息能被计算机识别、处理,需要将它们转变为二进制编码。

为什么计算机中采用二进制,而不是采用日常生活中使用的十进制?

图2-1 信息的种类

在早期设计的机械计算装置中使用的是十进制,利用齿轮的不同位置表示不同的数值。例如一个计算设备有十个齿轮,每一个齿轮有十个格,当小齿轮转一圈则大齿轮走一格。从而构成一个简单的十位十进制的数据表示设备,可以表示0~999999999的数字。

在电子计算机中,使用电子管来表示十种状态过于复杂,而使用电子管的开和关两种状态来表示二进制数据最为合理,如图2-2所示。在计算机中可以使用8个电子管的一组开关状态表示二进制数10100110,如图2-3所示。

图2-2 电子管开关状态

图2-3 电子管表示二进制数

随着计算机技术的飞速发展,各种存储设备仍然使用二进制的形式进行数据存储。

硬盘也称为磁存储设备,是通过电磁学原理读写数据,存储介质为磁盘或磁带,通过读写磁头改变存储介质中每个磁性粒子的磁极为两个状态,分别表示0和1,如图2-4所示。

光盘利用激光束在光盘表面存储信息,根据激光束和反射光的强弱不同,可以实现信息的读写。在写入光盘时会在光盘表面形成小凹坑,有坑的地方记录“1”,反之为“0”,如图2-5所示。

图2-4 磁存储介质表示0和1

图2-5 光盘表示0和1

计算机中采用二进制数有以下优点。

(1)可行性。电子元器件能表示的状态有限,若采用十进制编码,需要十种(0~9)状态;而采用二进制编码,只需要0、1两种状态,因此采用二进制数在技术上容易实现。例如,电子电路分为高电位和低电位,用低电位表示0,高电位表示1;磁芯的磁微粒分为正电极方向和负电极方向,用磁芯的负电极方向表示0,正电极方向表示1;脉冲分为有脉冲和无脉冲,用无脉冲表示0,用有脉冲表示1等。

(2)简易性。采用二进制有利于各种算法、规则的实现。数值计算是计算机的重要应用领域之一。二进制的算术运算规则简单,如A、B两数相乘,只有0×0=0、0×1=0、1×0=0、1×1=1共4种组合,而相应的十进制却有100种组合。

(3)适合逻辑运算。逻辑代数是逻辑运算的理论依据,二进制只有两个数码,正好与逻辑代数中的“真”和“假”相吻合。

(4)易于转换。二进制数与十进制数、八进制数、十六进制数易于互相转换。

(5)抗干扰能力强、可靠性高。因为使用“有脉冲、无脉冲”“高电位、低电位”“电磁南极、电磁北极”这样可对比的状态描述数字而无需准确测量具体值,因此当元器件受到一定程度的干扰时,仍能可靠地分辨出它表述的是什么数值。

2.1.5 存储单位

在计算机中,数据的存储单位有两种,具体如下。

(1)位(bit)。它是计算机中最小的信息单位。一“位”只能表示0和1中的一个,即一个二进制位,或存储一个二进制数位的单位。

(2)字节(Byte)。每8位二进制数为一个单位,称为字节(简写为B)。字节是计算机中数据存储的最基本单位,以下是计算机中各存储单位之间的关系。

1B=8bits,1KB=1024B,1MB=1024KB,1GB=1024MB,1TB=1024GB

1张JPG格式图片的存储空间大约为1MB,使用传统电子管存储和表示1MB数据需要220×8(约800万)个电子管。

2.1.6 数字在计算机中的表示

计算机最早被发明时的主要用途就是数学计算,数字在计算机中以二进制数的形式存储。

在计算机中采用固定数目的二进制位数来表示数字,称为机器数。机器数的表示范围受计算机字长的限制,一般字长为8、16、32或64位,如果数值超出机器数能表示的范围,就会出现“溢出”错误。

存放的数值有正、负之分,通常把一个二进制数的最高位作为符号位。规定“0”表示正号,“1”表示负号。

由于数值不仅有正负之分,同样可能有小数部分,因此还需要存储其小数点的位置。在计算机中采用约定小数点位置的方法,解决小数点的问题。

1.定点数

定点数是指小数点位置固定的数,它分定点纯整数和定点纯小数。

(1)定点纯整数是小数点位置固定在二进制数最低位的后面。

例如:为了便于理解,假设计算机中每个数值使用8位模式表示,即表示一个数字使用8位二进制数(第一位为符号位)。要存储纯整数-11,其整数部分对应的二进制数是1011,符号为负号,因此存储为10001011。

(2)小数点位置固定在二进制数最高位的前面,称为定点纯小数。

例如:要存储纯小数-0.11,其小数部分对应的二进制数是1011,符号为负号,因此存储为10001011,只是小数点位置和纯整数不同。

注意

小数点的位置是约定的,实际不需要表示。受计算机字长和数据类型的限制,定点数能够表示数的范围非常有限。

2.浮点数

浮点数是既包含整数又包含小数的实数。为了便于存储和表示浮点数,采用类似于科学计数法的方式。任何一个二进制数都可以表示为N = 数符×尾数×2阶符×阶码

尾数的位数决定数的精度,阶码的位数决定数的范围。

浮点数表示法根据不同机器对字长的规定,分配不同的位数用于存放阶码、尾数、阶码的符号和尾数的符号。其格式为

例如:二进制数110.011,利用浮点数表示法可以有多种不同的表示。

110.011B=1.10011×2+10=11001.1×2-10=0.110011×2+11

其中采用最后一种方式进行浮点数表示,存储形式如下。

注意

多数机器都把尾数定义为纯小数,将小数点约定在尾数符号位与尾数之间。

3.原码、反码、补码

在现代计算机系统中,为了有符号数值的存储和计算,数值一律采用补码来表示和存储。原因在于,使用补码可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理,可以将减法运算转变为加法运算。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。计算机中,带符号的数有多种表示形式,一般采用原码、反码、补码(以下假设计算机中每个数值使用8位模式表示,即表示一个数字使用8位二进制数,最高位为符号位)。

(1)原码表示法。原码是机器数最简单的表示方法。用0表示正号、1表示负号,数值部分为真值的绝对值(真值为机器数所代表的数)。

(2)反码表示法。正数的反码与原码相同,负数的反码由原码的数值部分按位取反得到(即0变为1,1变为0)。

(3)补码表示法。正数的补码与原码、反码相同,负数的补码等于负数的反码加1。

0有唯一的补码,[+0]=[-0]=00000000。-0的补码为100000000(8个0),受8位字长限制,最高位1在运算过程中,由于没有电子元器件表示而丢失,从而使保留下来的结果恰好与+0的补码一致。

数字在计算机中原本可以使用原码进行存储和参与运算,而采用补码的主要原因是可以将计算中的减法运算转变为加法运算。

假设以8个二进制数表示一个数字,要计算数学表达式10-7的结果。首先,10-7可以看作10+(-7),则计算机需要计算10与-7的和。按照原码表示方法,10的原码是00001010,-7的原码是10000111,10+(-7)的原码计算表达式如下所示。

计算结果为10010001,对应十进制数为-17,结果显然不正确。

在进行含有负数的运算中使用补码的形式可以避免符号位参与运算时造成的错误结果。按照补码表示方法,10的补码是00001010,-7的补码是11111001,10+(-7)的补码计算表达式如下所示。

计算结果为9位二进制数,超出8位。将最高位(即最左边的1)舍去,得到结果为00000011,就是十进制数3,可见采用补码形式计算的结果正确。

2.1.7 计算机中的字符编码

在计算机中还有很多非数值数据,如文本字符等。在计算机中,字符数据也需要转换为二进制进行存储和处理。

在计算机中,常用的字符有128个,包括10个十进制的数码0~9、52个大小写英文字母A~Z及a~z、32个标点符号、运算符、专用符号和34个控制符。

为了便于通信,根据应用的不同计算机中采用多种类型的编码来表示字符数据,如ASCII编码、EBCDIC编码、GB2312编码、Unicode编码、UTF-8编码、Base64编码等。

其中使用范围最广、接受程度最高的是 ASCII(American Standard Code for Information Interchange,美国标准信息交换码)和 EBCDIC 码(扩展的 BCD 交换码)。微型计算机一般采用ASCII,它是通用的国际标准编码,有7位和8位两种版本。ASCII于1968年提出,大多数小型机和所有个人计算机都使用ASCII。

7位ASCII采用7位二进制数表示一个字符,由于7位二进制数表示的范围为0~127,恰好包含128个数字,用于表示常用的128个字符,如表2-2所示。每个字符占用1Byte的空间,即8位二进制数,最高位设置为0,其余7位表示ASCII值。

8位ASCII编码也称为扩展ASCII(Extended Binary_Coded Decimal Interchange Code,EBCDIC)。最高位为0时,编码与7位ASCII编码相同。最高位为1时,形成扩展ASCII。

表2-2 ASCII表

2.1.8 计算机中的汉字编码

7位的ASCII只能对应128个字符,8位的EBCDIC最多对应256个字符,都无法对几万个汉字进行编码。

我国于1981年颁布了《信息交换用汉字编码字符集——基本集》,即国家标准GB2312—80,简称国标码。基本集共收集汉字6 763个,其中常用一级汉字3 755,二级汉字3 008个。GB2312—80编码用2个字节(16位)表示一个汉字,所以理论上最多可以表示256×256=65 536个汉字。例如汉字“大”字的国标码为十六进制数3473H。

由于汉字数量庞大、编码复杂,所以计算机输入、存储、显示汉字时使用不同编码。

1.输入码

通过键盘向计算机中输入汉字所使用的编码为输入码,也称外码。

例如,以拼音为基础的拼音类输入法,包括搜狗输入法、智能 ABC、微软全拼等;以字形为基础的字形类输入法,如五笔字形;以拼音、字形混合为基础的混合类输入码,如自然码。随着拼音类输入法的识别率不断提高,拼音类输入法已被广泛使用。

2.机内码

机内码也称内码,是汉字在计算机内部存储、处理和传输时使用的编码。在计算机内部,为了区分汉字编码和ASCII字符,将国标码每个字节的最高位由0改为1,构成汉字的机内码,即

汉字内码=汉字国标码+(8080)16

例如:

3.输出码

输出码也称汉字字型码,指汉字字库中存储的汉字字型的数字化信息,用于汉字的显示或打印输出。不同的汉字字库存放不同形状的汉字字型(即字体),如宋体、楷体、隶书等,分为点阵和矢量两种表示方法。

用点阵表示字型时,将一个汉字放在一个多行多列的网格中,有笔画通过的网格用二进制位1表示,没有笔画通过的网格用二进制位0表示,这样就构成汉字的点阵,如图2-6所示。一般有16×16、24×24、48×48、64×64点阵,行列数越大,字型质量越高,所占空间就越大。

图2-6 点阵字库

汉字字型码以二进制数形式保存在存储器中,构成汉字字库。每个汉字在字库中都占有一个固定大小的连续存储空间,如48×48点阵,需要288 (=48×48÷8)Byte空间存放一个汉字的字型码。

矢量表示方式存储的是描述汉字字型的轮廓特征,当要输出汉字时,通过计算机的计算由汉字字型描述生成所需大小和形状的汉字点阵。矢量表示方式与分辨率无关,因此可以产生高质量的汉字输出。Windows系统中使用的TrueType技术就是汉字的矢量表示方式。

注意

在计算汉字字型码的存储空间时,需要将点阵相乘结果除以8是为了将二进制数转换成相应的字节数。