计算机导论
上QQ阅读APP看书,第一时间看更新

1.2 计算机中信息的表示与编码

设计计算机的最初目的是进行数值计算,所以计算机中首先存储和表示的数据就是数值信息。但随着计算机应用的发展,现在的计算机数据以不同的形式出现,如数字、文字、声音、图形、视频信息等,如图1-13所示。但是,在计算机内部这些数据还是以数字形式存储和处理的。数据输入时要转换成二进制代码,输出时要还原成其原来的形式。因此,掌握信息编码的概念和处理技术是至关重要的。我们将一般形式的数据信息转换成二进制代码形式的过程称为信息的编码;反之,称为解码(也称译码)。不同类型的数据信息的编码方式不同。

图1-13 信息的分类与表现形式

1.2.1 数制及其转换

1. 数字体系

我们通常使用数码符号(简称数符)来表示数字,如罗马数字、阿拉伯数字,如图1-14所示。但在任何语言中的数符数量都是有限的,这就意味着在我们在表示数字的时候,数符需要被重复使用。为了重复使用这些有限的数符,人类在长期的实践中摸索出数字的两类表示体系:位置化数字体系和非位置化数字体系。

图1-14 采用罗马数字和阿拉伯数字的手表

(1)位置化数字体系。位置化数字体系使用相同的数码符号且数值大小与位置有关(数符依据位置的不同,代表不同的数量)。例如,阿拉伯数字10和1000中都含有1,但二者所表示的数量大小却相差100倍。

(2)非位置化数字体系。非位置化数字体系使用相同的数码符号且数值大小与位置无关(每个数符都代表固定的数量,不随其位置的变化而变化)。例如,罗马数字MC和MCⅢ中都含有C,但二者所表示的数量大小相同(都等于阿拉伯数字100)。

由于计算机使用的是位置化数字体系,因此在以后的学习中,我们讨论的都是位置化数字体系。

2. 数制及其属性

(1)数制。数制是一种表示和计算数的方法。日常生活中,我们习惯用十进制记数,有时也采用别的进制记数,例如,计算时间用六十进制、计算星期用七进制、计算月份用十二进制等。在计算机中表示和处理数据常用二进制、八进制和十六进制。

(2)数制的3个属性。数制具有以下3个属性。

① 基数:指数制中所用到的数码符号的个数。

例如,十进制数用0、1、2、3、4、5、6、7、8、9十个不同的数码符号表示,基数为10;而二进制数用0、1两个不同的数码符号表示,基数为2。

② 计数规则:指数制的进位和借位规则。

例如,十进制数的进位规则是“逢十进一”,借位规则是“借一当十”,如图1-15所示。

图1-15 十进制加减法

二进制数的进位规则是“逢二进一”,借位规则是“借一当二”,如图1-16所示。

图1-16 二进制加减法

③ 位权:不同位置上的1所表示的数值大小即为该位的位权。

例如,十进制数111.11=1×102+1×101+1×100+1×10-1+1×10-2,其中,102(100)、101(10)、100(1)、10-1(0.1)、10-2(0.01)就称为该十进制数各个位置上的位权。

二进制数111.11=1×22+1×21+1×20+1×2-1+1×2-2,其中,22(4)、21(2)、20(1)、2-1(0.5)、2-2(0.25)就称为该二进制数各个位置上的位权。

注意

任何一种数制的数都可以按位权进行展开,且展开之后的结果为十进制数,我们称这种方法为“位权展开法”,也称“幂级数展开法”。

例如,(101.01)B=1×22+0×21+1×20+0×2-1+1×2-2=(5.25)D,展开结果是十进制数5.25,其中,22、21、20、2-1、2-2称为该二进制数各个位置上的位权。

(257.2)O=2×82+5×81+7×80+2×8-1=(175.25)D,展开结果是十进制数175.25,其中,82、81、80、8-1称为该八进制数各个位置上的位权。

(A4D.4)H=10×162+4×161+13×160+4×16-1=(2637.25)D,展开结果是十进制数2637.25,其中,162、161、160、16-1称为该十六进制数各个位置上的位权。

3. 常用数制介绍

(1)十进制数(Decimal)。具体介绍如下。

基数及数码:基数为10,由0、1、2、3、4、5、6、7、8、9这10个不同的基本数码符号构成。

计数规则:逢十进一;借一当十。

位权:整数部分第i位的位权为10i-1;小数部分第j位的位权为10–j

字母表示:在十进制数的后面用大写字母D标示,如(120.45)D

现实意义与由来:十进制是人们日常生活中最习惯使用的数制,这可能与古人自然而然地首先使用十个手指计数有关。

(2)二进制数(Binary)。具体介绍如下。

基数及数码:基数为2,由0、1这两个不同的基本数码符号构成。

计数规则:逢二进一;借一当二。

位权:整数部分第i位的位权为2i-1;小数部分第j位的位权为2-j

字母表示:在二进制数的后面用大写字母B标示,如(101.11)B

现实意义与由来:二进制是计算机中使用最广泛的数制,这是因为冯·诺依曼型计算机中的数据以半导体元件的物理状态表示,两种稳定状态的元件最容易找到且最稳定,如继电器的接通和断开、晶体管的导通和截止、电脉冲电平的高和低等。而要找到具有10种稳定状态的元件来对应十进制的10个数码就困难得多。除此之外,二进制还与逻辑量天然吻合(0和1两个数码正好对应逻辑量False和True),可简化逻辑电路。正是因为电子原件的上述特性,二进制在计算机内部使用是再自然不过的事了。

(3)八进制数(Octal)。具体介绍如下。

基数及数码:基数为8,由0、1、2、3、4、5、6、7这8个不同的基本数码构成。

计数规则:逢八进一;借一当八。

位权:整数部分第i位的位权为8i-1;小数部分第j位的位权为8-j

字母表示:在八进制数的后面用大写字母O(或Q)标示,如(174.4)。

(4)十六进制数(Hexadecimal)。具体介绍如下。

基数及数码:基数为16,由0、1、2、3、4、5、6、7、8、9、A(10)、B(11)、C(12)、D(13)、E(14)、F(15)这16个不同的基本数码符号构成。

进位规则:逢十六进一;借一当十六。

位权:整数部分第i位的位权为16i-1;小数部分第j位的位权为16-j

字母表示:在十六进制数的后面用大写字母H标示,如(1AF.8)H

现实意义与由来:八进制数(23)、十六进制数(24)与二进制数存在联系。8等于2的3次方(1个八进制数可以用3个二进制数来表示,其读写效率是二进制的3倍);16等于2的4次方(1个十六进制数可以用4个二进制数来表示,其读写效率是二进制的4倍),所以计算机中冗长的二进制数据与短小的八进制及十六进制数据之间的换算都十分简便。这样一来,程序员们既避免了二进制数的冗长给读写带来的不便(二进制的弱点),又不影响他们关心二进制数每位情况的心思。因此,八进制、特别是十六进制已成为人机交流中最受欢迎的数制。

4. 常用数制间的转换

微型计算机内部采用二进制数操作,软件编程时通常采用八进制数和十六进制数,而人们日常习惯使用十进制数,因而要求计算机能对不同数制的数进行快速转换。当然,软件编程人员也必须熟悉这些数制间的转换方法。

(1)R进制转换为十进制。通过“位权展开法”,可以将R进制数转换为等值的十进制数。其位权展开过程式如下。

ana2a1.a-1a-mR=an×Rn-1+…+a2×R1+a1×R0+a-1×R-1+…+a-m×R-m

【例1-1】 分别把二进制数101.01、八进制数257.2和十六进制数A5E.2转换成十进制数。

解:(101.01)B=1×22+0×21+1×20+0×2-1+1×2-2=(5.25)D

(257.2)O=2×82+5×81+7×80+2×8-1=(175.25)D

(A5E.2)H=10×162+5×161+14×160+2×16-1=(2654.125)D

(2)十进制转换为R进制。整数部分和小数部分的转换方法是不同的,下面分别加以介绍。

① 整数部分的转换:采用“除基取余法”,即对十进制整数部分反复除以基数R,直到商为0为止,再把历次相除的余数按逆序(先得到的余数为低位,后得到的余数为高位)进行读取,即为R进制整数部分各位的数码。

【例1-2】 把十进制数25转换成二进制数。

所以,(25)D=(11001)B

注意

第一位余数是最低位,最后一位余数是最高位。

② 小数部分的转换:采用“乘基取整法”,即对十进制数的小数部分反复乘以基数R,直到乘积的小数部分为0(若不为0,则满足精度要求)为止,再把历次乘积的整数部分按顺序(先得到的整数为高位,后得到的整数为低位)读取,即为R进制小数部分各位的数码。

【例1-3】 把十进制数0.625转换成二进制数。

所以,(0.625)D=(0.101)B

注意

第一位整数是最高位,最后一位整数是最低位。

③ 对于既有整数又有小数的十进制数,可以先将整数部分和小数部分分别进行转换后,再合并得到所要的结果。

【例1-4】 把十进制数29.375转换成二进制数。

所以,(29.375)D=(11101.011)B

同理,采用“除8取余数,乘8取整数”的方法可将十进制数转换为八进制数;采用“除16取余数,乘16取整数”的方法可将十进制数转换为十六进制数。

(3)二进制数与八进制数、十六进制数的转换。下面对其分别加以介绍。

① 二进制数与八进制数的转换。由于八进制数的基数为8,二进制数的基数为2,两者满足8=23,故每1位八进制数可转换为等值的3位二进制数,反之亦然。因此,将八进制数转换为二进制数时,可采用“分组法”,即只需将八进制数的每1位直接转换成对应的3位二进制数即可。

【例1-5】 把二进制数10111011.10111转换成八进制数。

所以,(10111011.10111)B=(273.56)0

注意

二进制数转换成八进制数进行分组时,以小数点为界,整数部分从右往左3位为一组;小数部分从左往右3位为一组。若位数不够分组,只需在整数最高位前或小数最低位后添0补位。

【例1-6】 把八进制数273.56转换成二进制数。

所以,(273.56)0=(10111011.10111)B

② 二进制数与十六进制数的转换。同理,由于十六进制数的基数为16,二进制数的基数为2,两者满足16=24,故每1位八进制数可转换为等值的4位二进制数,反之亦然。因此,将十六进制数转换为二进制数时,可采用“分组法”,即只需将十六进制数的每1位直接转换成对应的4位二进制数即可。

【例1-7】 把二进制数1011001101.10101转换成十六进制数。

所以,(1011001101.10101)B=(2CD.A8)H

二进制数转换成十六进制数进行分组时,以小数点为界,整数部分从右往左4位为一组;小数部分从左往右4位为一组。若位数不够分组,只需在整数最高位前或小数最低位后添0补位。

【例1-8】 把十六进制数A7F.C3转换成二进制数。

所以,(A7F.C3)H=(101001111111.11000011)B

③ 八进制数与十六进制数的转换。八进制数与十六进制数之间的转换,一般以二进制作为桥梁,如图1-17所示,即先将八进制数或十六进制数转换为二进制数,再将二进制数转换成十六进制数或八进制数。

图1-17 二进制是进制转换的桥梁

【例1-9】 把八进制数351.74转换成十六进制数。

重新分组:

所以,(351.27)0=(E9.5C)H

1.2.2 数值信息的表示

数值信息在存储到计算机中之前,被转换成计算机可以识别的二进制形式的数据,但这里还需要解决以下问题。

问题1. 如何表示正负号。

对于正负号问题,计算机可做带符号位处理和不带符号位处理。带符号位处理时,可将正负号进行数字化表示(二进制0表示正号;1表示负号)后再进行存储。不带符号位处理,即不必存储符号位,这就意味着所分配的存储单元都可以用来存储数字,提高了存储效率。本书在接下来的章节中主要讨论带符号位的处理。

问题2. 如何表示小数点。

对于小数点问题,计算机中使用两种不同的表示格式:定点格式和浮点格式。若数的小数点位置固定不变则称为定点数;反之,若小数点的位置不固定则称为浮点数。

1. 机器数

在日常生活中,我们用正号(+)和负号(-)表示符号位;加绝对值表示数值位。我们把这种形式的数称为真值,如(+11)10、(-11)10、(+10110)2、(-10110)2

在计算机中,数的正负符号位也用二进制代码表示。规定最高位为符号位(用0表示“+”号;1表示“-”号),其余位仍然表示数值位。我们把这种在计算机内使用,连同正负号一起数字化的二进制数称为机器数(或机器码)。如:

机器数在进行计算时,符号位也一同参与运算。如:

我们发现,直接使用机器数进行运算时,会遇到减法问题。于是,我们试图采取对机器数编码来解决问题。

2. 机器数的3种编码方式

仅根据数值位表示方法的不同,机器数有3种编码方式,即原码、反码和补码,用以解决计算问题。

(1)原码。符号位用“0”表示正号,用“1”表示负号;数值位与真值保持一致。例如(为把问题简单化,我们假设机器字长为5位):

[+1101]真值→[01101]原码

[-1101]真值→[11101]原码

(2)反码。正数的反码与原码保持一致;负数的反码将原码的数值位按位取反(即“1”变“0”;“0”变“1”),符号位不变。例如:

[+1101]真值→[01101]原码→[01101]反码

[-1101]真值→[11101]原码→[10010]反码

(3)补码。正数的补码与原码保持一致;负数的补码将反码最低数值位加1,符号位不变。例如:

[+1101]真值→[01101]原码→[01101]反码→[01101]补码

[-1101]真值→[11101]原码→[10010]反码→[10011]补码

用补码进行计算时,可以统一加减法。将机器数表示成补码形式后,可解决困扰机器数多时的减法问题。因此,计算机中运算方法的基本思想是:各种复杂的运算处理最终都可分解为加、减、乘、除的四则运算与基本的逻辑运算,而四则运算的核心是加法运算(CPU的运算器中只有加法器)。可以通过补码运算化减为加实现减法运算,加减运算配合移位操作可以实现乘除运算。

(4)存储带符号整数。几乎所有的计算机都使用二进制补码来存储带符号整数。因为计算机CPU的运算器中只有加法器,而没有减法器,要把减法转化成加法来计算。于是,把机器数按补码形式进行存储,无疑是最好的选择。

【例1-10】 把十进制数+5表示成8位二进制补码。

解:(+5)D→(+00000101)真值→(00000101)原码→(00000101)反码→(00000101)补码

【例1-11】 把十进制数-5表示成8位二进制补码,如图1-18所示。

解:(-5)D→(-00000101)真值→(10000101)原码→(11111010)反码→(11111011)补码

图1-18 十进制负整数与3种编码之间的转换

【例1-12】 把二进制补码11111011还原成十进制整数。

解:(11111011)补码→(11111010)反码→(10000101)原码→(-00000101)真值→(-5)D

3. 机器数的两种存储格式

根据小数点位置固定与否,机器数又可以分为定点数和浮点数。

(1)定点数。若数的小数点位置固定不变则称为定点数。定点数又可分为定点小数和定点整数。

① 定点小数:是指小数点的位置固定在符号位与最高数据位之间。按此规则,定点小数的形式为X=X0.X1X2Xn,其中,X0为符号位,X1~Xn为数值位(也称尾数),X1为数值最高有效位,如图1-19所示。对用m+1个二进制位表示的定点小数来说,数值表示范围为∣N∣≤1-2m

图1-19 定点小数和定点整数的存储格式

② 定点整数:是指小数点的位置固定在最低数据位的右侧。按此规则,定点整数的形式为X=X0X1X2Xn,其中,X0为符号位,X1~Xn为数值位,Xn为数值最低有效位。对用n+1个二进制位表示的定点整数来说,此时数值范围为0≤N≤2n+1-1。

注意

定点数的小数点实际上只是一种人为规定,在机器中并没有专门的硬件设备来表示。故对于计算机本身而言,处理定点小数和处理定点整数在硬件构造上并无差异。

在计算机中,一般用8位、16位和32位等表示定点数(以16位最为常见)。在定点数中,无论是定点小数还是定点整数,计算机所处理的数必须在该定点数所能表示的范围之内,否则会发生溢出。溢出又可分为上溢和下溢。当数据大于定点数所能表示的最大值时,计算机将无法显示,称为上溢;当数据小于定点数所能表示的最小值时,计算机将其做“0”处理,称为下溢。当有溢出发生时,CPU中的状态寄存器PSW中的溢出标志位将置位,并进行溢出处理。

通常,整数多采用定点数表示。由于定点数的表示较为单一、呆板,数值的表示范围小、精度低且运算时易发生溢出,所以在数值计算时,大多采用浮点数来表示实数(带有整数部分和小数部分的数)。

(2)浮点数。若数的小数点位置不固定,则称之为浮点数。浮点表示法类似于十进制的科学计数法,如二进制数1110.011可表示为M=1110.011=0.1110011×2+4=1110011×2-3。这种表示法的好处显而易见,即使写在一张纸上,科学计数法也更短且更省空间。

① 浮点数的一般形式。根据以上形式可写出二进制所表示的浮点数的一般形式为MS×2±P,如图1-20所示。其中,纯小数S为数M的尾数,表示数的精度;数符Sf为尾数的符号位,表示数的正负;指数P为数M的阶码(也称指数位),表示小数点浮动的位置(或表示数的范围大小);阶符Pf为阶码P的符号位,表示小数点浮动的方向(往左移还是往右移)。

图1-20 浮点数存储格式

与定点数相比,用浮点数表示的数所表示的范围更大,精度也更高。

② 浮点数的规范化表示。为了浮点数表示的唯一性,并充分利用尾数的二进制位来表示更多的有效数字(提高精度),我们通常采用规格化形式表示浮点数,即将尾数的绝对值限定在以下范围内。

把不满足这一表示要求的尾数,变成满足这一表示要求的尾数的操作过程,称为浮点数的规格化处理,通过尾数移位和修改阶码来实现。

在规格化数中,若尾数用补码表示,则当M≥0时,尾数格式为S=0.1xx…x;当M<0时,尾数格式为S=1.0xx…x。

因此,补码表示时,若尾数的符号位与数值最高位不一致,即为规格化数。

【例1-13】 把十进制数7.5表示成二进制浮点规格化数。

解:将7.5转化为二进制数为111.1,111.1的规格化表示为0.1111×23。3是正数,故阶符为0,阶码为3,用二进制11表示。7.5是正数,故数符为0,尾数为0.1111,用二进制1111表示。拼接后为01101111。

所以,二进制浮点格式化数为01101111。

注意

小数点和尾数左边的位0并没有存储,它们是隐含的。

③ 存储实数与IEEE标准。

电气和电子工程师学会(Institute of Electrical and Electronics Engineers,IEEE)已定义了几种存储浮点数的标准。这里我们讨论其中两种最常见的——单精度和双进度。

单精度数格式,如图1-21所示,采用总共32位来存储一个浮点表示法的实数,其中,符号位占用1位(0为正;1为负);指数位占用8位(采用移码表示,偏移量为27-1=127);尾数位占用23位(无符号数)。因偏移量为127,所以该标准有时也称为“余127码”(Excess_127)。

图1-21 单精度存储格式

双精度数格式,如图1-22所示,采用总共64位来存储一个浮点表示法的实数,其中,符号位占用1位(0为正;1为负);指数位占用11位(采用移码表示,偏移量位为210-1=1023);尾数位占用52位(无符号数)。因偏移量为1023,所以该标准有时也称为“余1023码”(Excess_1023)。

图1-22 双精度存储格式

(3)定点数与浮点数的比较。具体比较如下。

表示范围:浮点表示法所能表示的数值范围远远大于定点表示法。

表示精度:对于字长相同的定点数与浮点数来说,浮点数虽然扩大了数的表示范围,但这是以降低精度为代价的,也就是说数轴上各点的排列更稀疏了。

运算复杂度:浮点运算要比定点运算复杂。

溢出难易度:定点运算时,当运算结果超出数的表示范围时,就发生溢出。浮点运算时,当运算结果超出尾数S的表示范围时,不一定溢出。只有当阶码P也超出所能表示的范围时,才一定发生溢出。因此,浮点数的健壮性较定点数更好。

1.2.3 信息单位

1948年,香农发表论文《通信的数学理论》,提出“信息熵”的概念,才解决了对信息的量化度量问题。文中香农首次用数学语言阐明了概率与信息冗余度之间的关系——任何信息都存在冗余。他借鉴热力学熵的概念,把信息中排除冗余后的平均信息量称为信息熵,并给出了计算信息熵的数学表达式,即著名的信息熵计算公式:

H(x)=-∑p(xi) log(2, p(xi) ) (i=1, 2, …, n

香农把信息熵定义为离散随机事件的出现概率。这表明了他对信息的理解,即信息是用来减少随机不定性的东西。

如果上式中的对数log是以2为底,那么计算出的信息熵就以比特(bit)为单位。今天在计算机和通信中广泛使用的字节(Byte)、千字节(KB)、兆字节(MB)、吉字节(GB)等单位都是从比特(bit)演化而来的。比特的出现标志着人类知道了如何计量信息量。

正是由于香农的信息论为明确什么是信息量做出了决定性的贡献,因此他被誉为“信息论之父”,如图1-23所示。

图1-23 香农(1916~2001年)

1. 计算机中最小的信息量单位——bit

单位由来:信息熵公式中对数log若以2为底,则计算出来的信息熵就以bit为单位。bit来自英文binary digit,直译为二进制位,音译为比特位,简称位。

单位规定:由信息熵公式可知,如果一个事件发生的概率是50%,那么它恰好包含了1比特的信息。在计算机科学中,我们把1位二进制数码所能表示的信息量称为1 bit(1比特)。它是构成信息的最小信息量单位。因此,愈多的比特位组合在一起,就可以表现愈复杂的信息。

位与信息量间的增长关系:一个二进制位只能表示0或1两种状态,要表示更多信息,就得把多个位组合成一个整体。例如:

1 bit所表示的信息量为21,取值为0,1。

2 bit所表示的信息量为22,取值为00,01,10,11。

3 bit所表示的信息量为23,取值为000,001,010,100,011,101,110,111。

由此看来,信息用二进制表示时,寄存器每增加1位,信息量就增长1倍。

2. 计算机中最基本的信息量单位——Byte

单位由来,从比特(bit)演化而来,是计算机中最基本的信息量单位。

字节多用于计算存储容量和传输容量。很多有关信息识别、存储和处理的单位都是在字节基础上制定的,因此字节也被认为是计算机中最基本的信息识别、存储和处理单位。

例如,内存按字节划分存储单元(微机内存中的1个小格就只能存放一位数据,8个连续的小格子合在一起就组成一个字节),并按字节进行编址,即为内存地址。虽然计算机中信息存储的最小单位是位,但硬件(如CPU)通过地址总线所能访问或控制的最小存储单元是字节。

单位规定:我们把8个连续的二进制位称为1个字节,即8 bit=1 Byte(简写为B)。如果要控制某1位,我们是通过位运算符和软件来实现的。

衍生单位:由于字节仍是一个很小的容量单位,为了方便标识和计算,KB、MB、GB、TB、PB等大容量单位被广泛使用。它们之间的数量转换关系如下。

千字节KB:1 KB=210B (1024 B)。

兆字节MB:1 MB=210KB (1024 KB)。

吉字节GB:1 GB=210MB (1024 MB)。

太字节TB:1 TB=210GB (1024 GB)。

皮字节PB:1 PB=210TB (1024 TB)。

3. 计算机中最常用的信息量处理单位——word

单位由来:从字节(Byte)演化而来。计算机进行数据处理时,一次存取、加工和传送的二进制位组,称为一个字。通常一个字是由一个或多个字节所组成的二进制位组。

单位规定:CPU在单位时间内一次所能处理的二进制位组称为字。我们把一个字的长度(即二进制位组的位数)称为字长,单位为bit。字长是计算机系统结构中的一个重要的性能指标,如32 bit处理器、64 bit处理器。

1.2.4 非数值信息的表示

编码(或代码)通常指一种在人和机器之间进行信息转换的系统体系。编码是人们在实践中逐步创造的一种用较少的符号来表达较复杂信息的表示方法。如我们前面谈到的数字,实际上就是一种编码,用一串数符代表规模更大的数。人们用0~9这10个数字的组合,表达的概念进不止10个数。编码的基本目的是为了信息交流。人们研究编码,就是为了以更简便的形式表达更丰富的信息。

随着现代计算机运用的深入,计算机不仅仅用来进行科学计算,实际上更多地是用于处理人们日常工作和生活中最常使用的信息,也就是所谓的非数值型数据,包括语言文字、逻辑语言等非数值信息。计算机中使用了不同的编码来表示和存储数字、文字符号、声音、图片和图像(视频)信息。计算机科学中,研究编码的目的是为了方便计算机表示、处理和存储各种类型的信息。但由于计算机硬件能够直接识别和处理的只是0、1这样的二进制信息,因此必须研究在计算机中如何用二进制代码来表示和处理这些非数值型数据。

1. 字符的编码

字符是非数值型数据的基础,字符与字符串数据是计算机中用得最多的非数值型数据。在使用计算机的过程中,人们需要利用字符与字符串编写程序,表示文字及各类信息,以便与计算机进行交流。为了使计算机硬件能够识别和处理字符,必须对字符按一定规则用二进制进行编码,使得系统里的每一个字母有唯一的编码。文本中还存在数字和标点符号,所以也必须有它们的编码。简单地说,所有的字母、数字和符号都要编码,这样的系统称为字符编码集。

计算机是美国人首先发明的,他们最先制定了符合他们使用需要的美国信息交换标准码(American Standard Code for Information Interchange,ASCII)。

ASCII是由美国国家标准学会(American National Standard Institute,ANSI)制定的标准单字节字符编码方案,用于基于文本的数据。它最初是ANSI供不同计算机在相互通信时用来作为共同遵守的西文字符编码标准,后被国际标准化组织(International Organization for Standardization,ISO)定为国际标准,称为ISO 646标准,适用于所有拉丁文字母。

ASCII使用指定的7位或8位二进制数组合来表示128或256种可能的字符。

(1)标准ASCII。标准ASCII表如图1-24所示,使用7位二进制数来表示所有的大写和小写字母、数字0~9、标点符号以及在美式英语中使用的特殊控制字符。其中,0~32及127(共34个)为控制字符或通信专用字符(其余为可显示字符)。控制符有LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通信专用字符有SOH(文头)、EOT(文尾)、ACK(确认)等。

图1-24 标准ASCII表

33~126(共94个)是字符。其中,48~58为0~9的阿拉伯数字;65~90为26个大写英文字母,97~122为26个小写英文字母,其余为一些标点符号、运算符号等。

值得注意的是,虽然标准ASCII码是7位编码,但由于计算机的基本处理单位为字节,因此以一个字节来存放一个标准ASCII码。其中,每个字节中的最高位在数据传输时用来作为奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定,正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位添1;偶校验规定,正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位添1。

(2)扩展ASCII。扩展ASCII采用8位二进制数进行编码,共256个字符。前128个编码为标准ASCII码,后128个称为扩展ASCII,许多系统都支持使用扩展ASCII。扩展ASCII允许将每个字符的第8位用于确定附加的128个特殊符号字符、外来语字母和图形符号。

ASCII是计算机世界里最重要的标准,但它存在严重的国际化问题。ASCII只适用于美国,它并不完全适用于其他以英语为主要语言的国家,更不用说在欧洲一些国家使用的非拉丁字母,包括希腊文、阿拉伯文、希伯来文和西里尔文等。对于东方以汉字为代表的象形文字巨大的集合更是无能为力。

2. 中文汉字的编码

汉字也是字符。与西文字符相比,汉字数量大、字形复杂、同音字多,这就给汉字在计算机内部的存储、传输、交换、输入、输出等带来了一系列的问题。为了能直接使用西文标准键盘输入汉字,还必须为汉字设计相应的输入编码,以适应计算机处理汉字的需要。

(1)国标码。1980年,我国颁布《信息交换用汉字编码字符集基本集》,代号为GB 2312—1980,是国家规定的用于汉字信息处理使用的代码依据,这种编码称为国标码。

在国标码的字符集中共收录了6763个常用汉字和682个非汉字字符(图形、符号)。汉字被分为两级,其中,一级汉字3755个,以汉语拼音为序排列;二级汉字3008个,以偏旁部首进行排列。

国际码采用16位的二进制数进行编码,即双字节字符集(double-byte character set,DBCS)。理论上最多可以表示256×256=65536个汉字。

(2)机内码。由于在计算机内部是以字节(8位)为单位对信息进行识别、存储和处理的,所以如果在机器内部直接使用代表汉字编码的国际码来存储汉字,必然引起汉字字符和英文字符在信息识别和处理时的相互冲突。例如,汉字字符“菠”的国际码为(0010010000110010)B,计算机无从识别这是一个国际码还是两个ASCII码。

为了使计算机有效地区分英文字符和中文字符,约定将国际码中每个字节的最高位设置为1;ASCII码的最高位设置为0。我们把这种经过约定后的国际码称为机内码。例如,汉字字符“菠”的机内码为(1010010010110010)B

(3)汉字输入码。实现汉字输入时,系统所使用的字母或数字的组合称为汉字的输入码,也称汉字外码。如五笔输入法、搜狗智能输入法等。

汉字输入通常有键盘输入、语音输入、手写输入等方法,都有各自的优、缺点。常用的键盘输入方式将每个汉字用一个或几个英文键表示,这种表示方法称为汉字的输入码。输入码与机内码不同,它是专为解决汉字输入设计的,汉字输入后仍是以机内码存储在计算机中的,这种转换由系统中特殊的部分自动进行。输入码的基本元素是标准键盘上可见的字母符号。汉字输入码的种类有很多,根据输入码的方式大体可分为以下4类。

数字编码:如电报码、区位码等,特点是难于记忆、不易推广。

字音编码:如拼音码等,特点是简单易学,但重码多。

字形编码:如五笔宇型、表形码等,特点是重码少、输入快,但不易掌握。

音形编码:如自然码、快速码等,特点是规则简单、重码少,但不易掌握。

(4)汉字输出码。实现汉字输出(如显示或打印)时,系统自动将代表汉字序列的国际码转换成代表汉字形状的字型码。目前主流的汉字字型码有点阵字型码和矢量字型码。

① 点阵字型码。目前普遍使用点阵方式表示汉字字形,我们称为点阵字型码。用点阵方式存储汉字字型信息的集合,称为汉字字模库,简称汉字字库。

当点阵为16×16位时,点阵字型码采用32个字节进行编码,即一个汉字的字型码为32个字节,如图1-25所示。

图1-25 汉字“中”16×16位点阵字模示例

② 区位码。国标GB 2312-80规定,所有的国标汉字与符号组成一个94×94位的方阵,在此方阵中,每一行称为一个“区”(区号为01~94),每一列称为一个“位”(位号为01~94),该方阵实际上组成了一共94个区,每个区内有94个位的汉字字符集,每一个汉字或符号在码表中都有一个唯一的位置编码,称为该字符的区位码。

使用区位码方法输入汉字时,必须先在表中查找汉字并找出对应的代码才能输入。区位码输入汉字的优点是无重码,而且输入码与内部编码的转换比较方便。

3. Unicode码

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想正确打开一个文本文件,就必须知道它正确的编码方式,否则用错误的编码方式解读就会出现乱码。可以想象,如果有一种编码,将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码,那么乱码问题就可以避免。

20世纪90年代,硬件及软件在内的多家主导厂商共同研制开发了Unicode编码。这种代码采用唯一16位来表示每一个符号。因此,Unicode由65536个不同的位模式组成,这足以表示用中文、日文和希伯来文等语言书写的文档资料。

Unicode即统一码,又称万国码,是一种以满足跨语言、跨平台进行文本转换、处理的要求为目的设计的计算机字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码。

Unicode的编码方式与ISP 10646的通用字元集(也称通用字符集)概念相对应,使用16位的编码空间,也就是每个字符占用2个字节。实际上,目前版本的Unicode尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。

在Unicode中收录汉字个数达27484个,包括简、繁体中文,以及日、韩文中使用到的几乎所有的汉字字符。Unicode的汉字编码在Windows系统中又称为CJK编码(中、日、韩统一编码)。