1 int x=-1;
第 3 版 · OCR 辅助 · 原书检索 · 文字用于定位,公式与图表请回原页核验 · 本次导入快照
### 1 int x=-1;
### 2 unsigned u=2147483648;
3
### 4 printf("x=8u=?n",x,x);
### 5 printf("u=}?n:,u,u);
上述C代码中,x为带符号整数,u为无符号整数,初值为2147483648(即21)。函数
printf()用来输出数值,指示符??????别用来以无符号整数和带符号整数的形式输出十
进制数的值。当在一个32位机器上运行上述代码时,它的输出结果如下:
x=4294967295=-1
u=2147483648=-2147483648
x的输出结果说明如下:因为一1的补码表示为11⋯1,所以当作为32 位无符号数来
解释(格式符为y时,其值为2-1=4 294967 296-1=4 294 967 295。
u的输出结果说明如下:2的无符号整数表示为100⋯0,当这个数被解释为32位带符号
整数(格式符为?时,其值为最小负数-22-1=-21=-2147483648(参见例2.12)。
在C语言中,如果执行一个运算时同时有无符号整数和带符号整数参加,那么,C编译
器会隐含地将带符号整数强制类型转换为无符号整数,因而会带来一些意想不到的结果。
例如,对于32位系统中的C语言表达式:
-2147483648<2147483647
若编译器按ISO C90标准规范进行处理,那么该表达式的结果为false。但是,在 ISO
C99 标准规范下编译,其结果则为 true。如果把上面的表达式转换为
-2147483647-1<2147483647
则在C90和C99标准下的结果都是 true。为什么会出现以上这种情况呢?
ISO C90标准规定,在21~22-1范围内的整数常量为unsigned int 型;C99标准规
第2章
33
<!-- page: 51 -->
计算机组成与系统结构(第3版)
34
定,在21~2-1范围内的整数常量为long long型;对于在0~2-1内的整数常量,C90
和C99标准都规定为int型。因此,2147483648(21)在C90中为无符号整型,在C99中为
带符号整型,而1和2147483 647(2-1)在C90和C99 中都是带符号整型。
对于C表达式“—2147483648<2147483647”,由于运算符“—”比“<”优先级高,编译
器会先处理“<”的左边部分,将—2147483648分为“—”和数字串“2147483648”两部分进行
处理。首先,编译器将2147483 648转换为二进制数1000 0000 ⋯ 0000(31个0),然后,对
“—”进行处理,将其转换为“取负”指令。对二进制数1000 0000 ⋯0000取负(各位取反,末
位加1)后结果不变。因而在处理条件表达式“-2147483648<2147483647”时,实际上是将
### 1000 0000 ⋯ 0000(31个0)和0111 1111⋯ 1111(31个 1)进行比较。
在ISO C90标准下,编译器将2147483648标识为无符号整型,因此条件表达式按无
符号整型进行比较,显然1000 0000⋯0000(31个0)大于01111111⋯1111(31个1),故比
较结果为 false。在C99标准下,常数2147483648和2147483647都是带符号整型,因此
条件表达式按带符号整型进行比较,显然1000 0000⋯ 0000(31个0)小于0111 1111⋯
1111(31个1),故比较结果为 true。
对于C表达式“—2147483647-1<2147483647”,因为其中的常数2147483 647和 1
在C90和C99中都是带符号整型,所以都按带符号整型进行比较。对于<的左部,编译器
将2147 483 647转换为二进制数0111 1111⋯ 1111(31个1),然后对其取负,得到1000 0000⋯
0001(中间30个0),再将其减1,得到1000 0000⋯0000(31个0),第一位是1,显然是负数。
对于>的右部0111 1111⋯ 1111(31个1),第一位为0,说明是正数。因为负数一定小于正
数,因而比较结果在 C90和 C99 中都是 true。
2.3实数的表示
计算机内部进行数据存储、运算和传送的部件位数有限,因而用定点数表示数值数据
时,其表示范围很小。n位带符号整数表示范围为-2"-'~(2"-(-1),运算结果很容易溢
出,此外,用定点数也无法表示大量带有小数点的实数。因此,计算机中专门用浮点数来表
示实数。
2.3.1浮点数的表示格式
对于任意一个实数X,可以表示为
X=(-1)?×M×RF
其中,S取值为0或1,用来决定数X的符号,一般用0表示正,1表示负;M是一个二进制
定点小数,称为数X的尾数;E是一个二进制定点整数,称为数X的阶或指数;R是基数,
可以约定为2、4、16等。要确定一个实数的值,只要在默认基数R下,确定数符S、尾数M
和阶E就可以了。因此,浮点数格式只需规定S、M和E各自所用的位数、编码方式和所在
的位置,而基数R与定点数的小数点位置一样,是默认的,不需要明显地表示出来。一般尾
数用定点原码小数表示,指数用移码表示。
在IEEE 754浮点数标准被广泛使用之前,不同的计算机所用的浮点数表示格式各不
相同。例如,IBM370的 32 位短浮点数格式如下:
<!-- page: 52 -->
数据的机器级表示
01
78
31
数符
阶码
尾数
其中,第0位为数符S;第1~7位为7位移码表示的阶码E(偏置常数=64);第8~31位为
6位十六进制原码小数表示的尾数M。基数R为16,所以阶码变化1等于尾数移动4位。
例2.21 将十进制数65798转换为IBM370的32 位短浮点数格式。
解:因为(65798)1=(10106)16=(0.101060)×16?,所以数符S=0,阶码E=(64+
5)=(69)=(100 0101)?。
故用该浮点数形式表示如下:
0
1000101
### 0001 0000 0001 0000 0110 0000
用十六进制表示为4510 10 60H。
例 2.22 将十进制数65798 转换为下述 32 位浮点数格式。
01
89
31
数符
阶码
尾数
其中,第0位为数符S;第1~8位为8位移码表示的阶码E(偏置常数为128);第9~31位
为24位二进制原码小数表示的尾数。基数为2,规格化尾数形式为±0.1bb⋯b,其中第一位
1不明显表示出来,这样可用23个数位表示24位尾数。
解:因为(65798)1。=(10000 0001 0000 0110)?=(0.1000 0000 1000 0011 0)?×2”,所
以数符S=0,阶码 E=(128+17)=(145)?=(10010001)z。
故用该浮点数形式表示为
### 0 100 10001 000 0000 1000 0011 0000 0000
用十六进制表示为48 80 83 00H。
上述格式的规格化浮点数的表示范围如下。
正数最大值:0.11⋯1×21~'=(1-2-*)×21"。
正数最小值:0.10⋯0×2⋯=(1/2)×2-126=2-12°。
因为原码是关于原点对称的,故该浮点格式的范围是关于原点对称的,如图2.1所示。
负上溢
可表示的负数
零
可表示的正数
负下溢
正下溢
正上溢
-(1-2-24)×2127
-2-129
0
2-129
图2.1 浮点数的表示范围
(1-22?)×21”数轴
在图2.1中,数轴上有4个区间的数不能用浮点数表示。这些区间称为溢出区,接近0
的区间为下溢区,向无穷大方向延伸的区间为上溢区。
根据浮点数的表示格式,只要尾数为0,阶取任何值其值都为0,这样的数被称为机器
零,因此机器零不唯一。通常用阶码和尾数同时为0来唯一表示机器零。即当结果出现尾
数为0时,不管阶码是什么,都将阶码取为0。也有的计算机将下溢区(指数过小)的数近似
成机器零。机器零有+0和一0之分。
第2章
35
<!-- page: 53 -->
计算机组成与系统结构(第3版)
36
2.3.2浮点数的规格化
浮点数尾数的位数决定浮点数的有效数位,有效数位越多,数据的精度越高。为了在浮
点数运算过程中尽可能多地保留有效数字的位数,使有效数字尽量占满尾数数位,必须在运
算过程中对浮点数进行“规格化”操作。对浮点数的尾数进行规格化,除了能得到尽量多的
有效数位以外,还可以使浮点数的表示具有唯一性。
从理论上来讲,规格化数的标志是真值的尾数部分中最高位具有非零数字。也就是说,
若基数为R,则规格化数的标志是,尾数部分真值的绝对值大于或等于1/R。若浮点数的基
数为2,则尾数规格化的浮点数形式应为±0.1bb⋯b×2(这里b是0或1)。
规格化操作有两种:“左规”和“右规”。当有效数位进到小数点前面时,需要进行右规。
右规时,尾数每右移一位,阶码加1,直到尾数变成规格化形式为止,右规时指数会增加,因
此有可能溢出;当出现形如±0.0⋯0bb⋯b×2F的运算结果时,需要进行左规,左规时,尾数
每左移一位,阶码减1,直到尾数变成规格化形式为止。
2.3.3IEEE 754 浮点数标准
直到20世纪80年代初,浮点数表示格式还没有统一标准,不同厂商计算机内部浮点数
表示格式不同,在不同结构的计算机之间进行数据传送或程序移植时,必须进行数据格式的
转换,而且,数据格式转换还会带来运算结果的不一致。因而,20世纪70年代后期,IEEE
成立委员会着手制定浮点数标准,1985年完成了浮点数标准IEEE 754的制定。
目前,几乎所有计算机都采用IEEE754标准表示浮点数。在这个标准中,提供了两种
基本浮点格式:32 位单精度和64位双精度格式,如图 2.2 所示。
1位8位
23位
符号
阶码
尾数
(a)32位单精度格式
1位
11位
52位
符号
阶码
尾数
(b)64位双精度格式
图2.2 IEEE 754浮点数格式
32位单精度格式中包含1位符号s、8位阶码e和23位尾数f;64位双精度格式包含1
位符号s、11位阶码e和52位尾数f。其基数隐含为2;尾数用原码表示,第一位总为1,因
而可在尾数中缺省第一位的1,称为隐藏位,使得单精度格式的23位尾数实际上表示了24
位有效数字,双精度格式的52位尾数实际上表示了53位有效数字。IEEE754规定隐藏位
1的位置在小数点之前。
IEEE754标准格式中,指数用移码表示,偏置常数并不是通常n位移码所用的2"-',而
是2"1—1,因此,单精度和双精度浮点数的偏置常数分别为127和1023。IEEE754的这种
“尾数带一个隐藏位,偏置常数用2°-1-1”的做法,不仅没有改变传统做法的计算结果,还带
来以下两个好处。
<!-- page: 54 -->
数据的机器级表示
(1)尾数可表示的位数多一位,因而使浮点数的精度更高。
(2)指数的可表示范围更大,因而使浮点数范围更大。
对于IEEE754标准格式的数,一些特殊的位序列(如阶码为全0或全1)有其特别的解
释。表2.2给出了对各种形式的数的解释。
表 2.2 IEEE 754 浮点数的解释
值的类型
单精度(32位)
双精度(64位)
符号
阶码
尾数
值
符号
阶码
尾数
值
正零
0
0
0
0
0
0
0
0
负零
1
0
0
-0
1
0
0
-0
正无穷大
0
255(全1)
0
0
2047(全1)
0
a
负无穷大
1
255(全1)
0
一c0
1
2047(全1)
0
一
无定义数
0或1
255(全1)
≠0
NaN
|0或1 2047(全1)
≠0
NaN
规格化非零正数
0
0<e<255
f
2r-127(1.f)
0
0<e<2047
f
2-1023(1.f)
规格化非零负数
1
0<e<255
f
-2-(1.f)
1
0<e<2047
f
-2-l(1.f)
非规格化正数
0
0
f≠0
### 2 *(0.f)
0
0
f≠0
### 2 l(0.f)
非规格化负数
1
0
f≠0 -2-H*(0.f)
1
0
f≠0
—2-102?(0.f)
在表 2.2 中,对 IEEE 754中规定的数进行了以下分类。
1.全0阶码全0尾数:+0/-0
IEEE754的零有两种表示:+0和-0。零的符号取决于数符s。一般情况下,+0和
一0是等效的。
2.全0阶码非 0尾数:非规格化数
非规格化数的特点是阶码为全 0,尾数高位有一个或几个连续的0,但不全为0。因此
非规格化数的隐藏位为0,并且单精度和双精度浮点数的指数分别为一126或—1022,故数
值分别为(一1)'×0.f×2~126和(一1)'×0.f×2~1。非规格化数可用于处理阶码下溢,使
得出现比最小规格化数还小的数时程序也能继续进行下去。
3.全1阶码全0尾数:+o/-
引入无穷大数使得在计算过程出现异常的情况下程序能继续进行下去,并且可为程序
提供错误检测功能。+~在数值上大于所有有限数,一一则小于所有有限数,无穷大数既可
作为操作数,也可能是运算的结果。当操作数为无穷大时,系统可以有两种处理方式。
(1)产生不发信号的非数NaN。如++(-~),+-(+?~/等。
(2)产生明确的结果。如5+(+o)=+~,(+~)+(+0)=+~,5-(+~)=
一?一0)-(+0)=-~等。
4.全1阶码非0尾数:NaN
NaN(not a number)表示一个没有定义的数,称为非数。表 2.3给出了能产生不发信
号(静止的)NaN 的计算操作。
第2章
37
<!-- page: 55 -->
计算机组成与系统结构(第3版)
表2.3 产生不发信号 NaN 的操作
运 算 类型
产生不发信号NaN的计算操作
38
所有
对通知 NaN的任何计算操作
加减
无穷大相减:(+~)+(-≈)、(+)-(+???
乘
0×0
除
0/0或/
求余
X MOD0或MOD y
平方根
√x且x<0
可用尾数取值的不同来区分是“不发信号NaN”还是“发信号NaN”。当最高有效位为
1时,为不发信号(静止的)NaN,当结果产生这种非数时,不发“异常”通知,即不进行异常处
理;当最高有效位为0时为发信号(通知的)NaN,当结果产生这种非数时,则发一个异常操
作通知,表示要进行异常处理。
5.阶码非全0且非全1:规格化非0数
对于阶码范围在1~254(单精度)和1~2046(双精度)的数,是一个正常的规格化非0
数。根据 IEEE754的定义,这种数的指数的范围应该是一126~+127(单精度)和—1022~
+1023(双精度),其值的计算公式分别为
(-1)'×1.f×2~12? 和 (-1)×1.f×2~1023
例2.23 将十进制数-0.75转换为IEEE 754的单精度浮点数格式表示。
解:(一0.75)=(-0.11)?=(-1.1)?×2-1=(-1)'×1.f×2~l*,所以s=1,f=
0.100⋯0,e=(127-1)o=(126)o=(01111110)?,规格化浮点数表示为10111 1110 1000 0000⋯
### 0000 000,用十六进制表示为 BF40 0000H。
例2.24 求 IEEE 754单精度浮点数 COA0 0000H 的值是多少。
解:求一个机器数的真值,就是将该数转换为十进制数。首先将COA? 0000H 展开为
一个32 位单精度浮点数:1 10000001 010 0000⋯0000。据 IEEE 754单精度浮点数格式可
知,符号s=1,尾数f=(0.01)?=(0.25),阶码e=(10000001)。=(129)。,所以,其值为
(-1)*×1.f×2~127=(-1)1×1.25×2129-12?=-1.25×22=-5.0。
IEEE 754标准的单精度和双精度格式的特征参数见表 2.4。
表2.4 IEEE 754 浮点数格式参数
参 数
单精度浮点数
双精度浮点数
字宽(位数)
32
64
阶码宽度(位数)
8
11
阶码偏置常数
127
1023
最大指数
127
1023
最小指数
-126
-1022
尾数宽度
23
52
<!-- page: 56 -->
数据的机器级表示
续表
参 数
单精度浮点数
双精度浮点数
阶码个数
254
2046
尾数个数
2
2
值的个数
1.98×231
1.99×2
数的量级范围
10-*~10+3m
10~*~10+*
IEEE 754用全0阶码和全1阶码表示一些特殊值,如0、~和NaN,因此,除去全0和
全1阶码后,单精度和双精度格式的阶码个数分别为254和2046,最大指数为127和1023。
单精度规格化数的个数为254×2=1.98×2,双精度规格化数的个数为2046×22=1.99×
2。根据单精度和双精度格式的最大指数分别为127和1023,可以得出数的量级范围分别
为10 ~10+*和10~308~10+30??
IEEE 754除了对上述单精度和双精度浮点数格式进行了具体的规定以外,还对单精度
扩展和双精度扩展两种格式的最小长度和最小精度进行了规定。例如,IEEE 754 规定,双
精度扩展格式必须至少具有64位有效数字,并总共占用至少79位,但没有规定其具体的格
式,处理器厂商可以选择符合该规定的格式。
例如,Intelx87 FPU采用80位双精度扩展格式,包含4个字段:1位符号位s、15位阶
码e(偏置常数为16383)、1位显式首位有效位(explicit leading significand bit)j和63位尾
数f。Intel公司采用的这种扩展浮点数格式与IEEE 754规定的单精度和双精度浮点数格
式的一个重要的区别是,它没有隐藏位,有效位数共64位。Intel安腾FPU采用82位扩展
精度。
又如,SPARC和PowerPC处理器中采用128位扩展双精度浮点数格式,包含1位符号
位s、15位阶码e(偏置常数为16383)和112 位尾数f,采用隐藏位,所以有效位数为
113位。
2.3.4C语言中的浮点数类型
C语言中有 float和 double两种不同浮点数类型,分别对应IEEE 754单精度浮点数格
式和双精度浮点数格式,相应的十进制有效数字位数分别为7位和17位。
C语言对于扩展双精度的相应类型是long double,但是long double的长度和格式随编
译器和处理器类型的不同而有所不同。例如,Microsoft Visual C++6.0 版本以下的编译器
都不支持该类型,因此,用其编译出来的目标代码中long double和 double一样,都是64位
双精度;在IA-32上使用GCC编译器时,long double类型数据采用2.3.3节中所述的 Intel
x86 FPU的80位双精度扩展格式表示;在 SPARC和 PowerPC处理器上使用GCC编译器
时,long double类型数据采用2.3.3节中所述的128位双精度扩展格式表示。
当在 int、float 和 double 等类型数据之间进行强制类型转换时,程序将得到以下数值转
换结果(假定 int为32位)。
(1)从 int 转换为float 时,不会发生溢出,但可能有数据被舍入。
(2)从int或 float转换为double时,因为double的有效位数更多,故能保留精确值。
(3)从 double转换为float 时,因为float 表示范围更小,故可能发生溢出,此外,由于有
第2章
39
<!-- page: 57 -->
计算机组成与系统结构(第3版)
40
效位数变少,故可能被舍入。
(4)从 float或 double转换为int时,因为int没有小数部分,所以数据可能会向0方向
被截断。例如,1.9999被转换为1,-1.9999被转换为一1。此外,因为int的表示范围更小,
故可能发生溢出。将大的浮点数转换为整数可能会导致程序错误,这在历史上曾经有过惨
痛的教训。
1996年6月4日,Ariana5火箭初次航行,在发射仅仅37s后,偏离了飞行路线,然后解
体爆炸,火箭上载有价值5亿美元的通信卫星。根据调查发现,原因是控制惯性导航系统的
计算机向控制引擎喷嘴的计算机发送了一个无效数据。它没有发送飞行控制信息,而是发
送了一个异常诊断位模式数据,表明在将一个64位浮点数转换为16位带符号整数时,产生
了溢出异常。溢出的值是火箭的水平速率,这比原来的Ariana4火箭所能达到的速率高出
了5倍。在设计Ariana 4火箭软件时,设计者确认水平速率决不会超出一个16位的整数,
但在设计Ariana5时,他们没有重新检查这部分,而是直接使用了原来的设计。
在不同数据类型之间转换时,往往隐藏着一些不容易被察觉的错误,这种错误有时会带
来重大损失,因此,编程时要非常小心。
例2.25 假定变量i、f、d的类型分别是int、float 和 double,它们可以取除+≈、-
和NaN 以外的任意值。请判断下列每个C语言关系表达式在32 位机器上运行时是否
永真。
A.i==(int)(float)i
B.f==(float)(int)f
C.i==(int)(double)i
D.f==(float)(double)f
E.d==(float)d
F.f==-(-f)
G.(d+f)-d==f
解:
A.不是。int精度比float高,当i转换为float后再到int时,有效位数可能丢失。
B.不是。float有小数部分,当f转换为int后再到float时,小数部分可能会丢失。
C.是。double比 int有更大的精度和范围,当i转换为double后再到int时数值不变。
D.是。double 比 float有更大的精度和范围,当f转为double后再到 float 时数值不变。
E.不是。double 比 float有更大的精度和范围,当d转换为float 后数值可能改变。
F.是。浮点数取负就是简单将数符取反。
G.不是。例如,当d=1.79×10、f=1.0时,左边为0(因为d+f时f需向d对阶,
对阶后f的尾数有效数位被舍去而变为0,故d+f仍然等于d,再减去d后结果为0),而
右边为1。
2.4非数值数据的编码表示
逻辑值、字符等数据都是非数值数据,在机器内部它们也用二进制表示。下面分别介绍
这些非数值数据的编码表示。
<!-- page: 58 -->
数据的机器级表示
2.4.1逻辑值
通常每个字或其他可寻址单位(字节、半字等)作为一个整体数据进行处理。但在某些
情况下也需要将一个n位数据看成是由n个1位数据组成,每个取值为0或1。例如,有时
需要存储一个二进制数据阵列,阵列中的每项只能取值1或0;有时可能需要提取一个数据
项中的某位进行诸如“置位”或“清0”等操作。当数据以这种方式看待时,就被认为是逻辑
数据。因此n位二进制数可表示n个逻辑值。逻辑数据只能进行按位逻辑运算,如按位
“与”、按位“或”、逻辑左移、逻辑右移等。
逻辑数据和数值数据都是一串0/1序列,在形式上无任何差异,需要通过指令的操作码
类型来识别它们。例如,逻辑运算指令处理的是逻辑数据,算术运算指令处理的是数值
数据。
2.4.2西文字符
西文由拉丁字母、数字、标点符号及一些特殊符号所组成,它们统称为字符(character)。
所有字符的集合叫作字符集。字符集中每一个字符都有一个代码(即二进制编码的0/1序
列),构成了该字符集的代码表,简称码表。码表中的代码具有唯一性。
字符主要用于外部设备和计算机之间交换信息。一旦确定了所使用的字符集和编码方
法后,计算机内部所表示的二进制代码和外部设备输入、打印和显示的字符之间就有唯一的
对应关系。
字符集有多种,每一个字符集的编码方法也多种多样。目前计算机中使用最广泛的西
文字符集及其编码是 ASCII码,即美国标准信息交换码(American Standard Code for
Information Interchange),ASCII字符编码见表2.5。
表 2.5 ASCII 码表
b?b?b?b?
000
001
010
b?b?b?
011
100
101
110
111
0000
NUL
DLE
SP
0
@
P
p
0001
SOH
DC1
!
1
A
Q
a
q
0010
STX
DC2
"
2
B
R
b
r
0011
ETX
DC3
#
3
C
S
c
8
0100
EOT
DC4
$
4
D
T
d
t
0101
ENQ
NAK
%
5
E
U
e
u
0110
ACK
SYN
8.
6
F
V
f
v
0111
BEL
ETB
7
G
W
g
w
1000
BS
CAN
(
8
H
X
h
x
1001
HT
EM
)
9
1
Y
y
第2章
41
1010
LF
SUB
:
J
Z
j
2
<!-- page: 59 -->
计算机组成与系统结构(第3版)
续表
42
b?b?b?b?
000
001
010
b?b?b?
011
100
101
110
111
1011
VT
ESC
+
;
K
[
k
(
1100
FF
FS
·
<
L
\
1
l
1101
CR
GS
一
=
M
]
m
1110
SO
RS
>
N
n
1111
SI
US
/
?
0
0
DEL
从表2.5中可看出每个字符都由7个二进位b?b?b?b?b?b?b?表示,其中b?b?b?是高位
部分,b?b?b?b?是低位部分。一个字符在计算机中实际上是用8位表示的。一般情况下,最
高一位b,为0。在需要奇偶校验时,这一位可用于存放奇偶校验位。从表 2.5中可看出
ASCII字符编码有以下两个规律。
(1)字符0~9这10个数字字符的高3位编码为011,低4位分别为0000~1001。当去
掉高3位时,低4位正好是0~9这10个数字的8421码。这样既满足了正常的排序关系,
又有利于实现 ASCII码与十进制数之间的转换。
(2)英文字母字符的编码值也满足正常的字母排序关系,而且大、小写字母的编码之间
有简单的对应关系,差别仅在bs这一位上,若这一位为0,则是大写字母;若为1,则是小写
字母。这使得大、小写字母之间的转换非常方便。
2.4.3汉字字符
西文是一种拼音文字,用有限的几个字母可以拼写出所有单词。因此西文中仅需要对
有限个少量的字母和一些数学符号、标点符号等辅助字符进行编码,所有西文字符集的字符
总数不超过256个,所以使用7个或8个二进位就可表示。中文信息的基本组成单位是汉
字,汉字也是字符。但汉字是表意文字,一个字就是一个方块图形。计算机要对汉字信息进
行处理,就必须对汉字本身进行编码,但汉字的总数超过6万字,数量巨大,给汉字在计算机
内部的表示、汉字的传输与交换、汉字的输入和输出等带来了一系列问题。为了适应汉字系
统各组成部分对汉字信息处理的不同需要,汉字系统必须处理以下几种汉字代码:输入码、
内码、字模点阵码。
1.汉字的输入码
由于计算机最早是由西方国家研制开发的,最重要的信息输入工具——键盘——是面
向西文设计的,一个或两个西文字符对应着一个按键,非常方便。但汉字是大字符集,专门
的汉字输入键盘由于键多、查找不便、成本高等原因而几乎无法采用。目前来说,最简便、最
广泛采用的汉字输入方法是利用英文键盘输入汉字。由于汉字字数多,无法使每个汉字与
西文键盘上的一个键相对应,因此必须使每个汉字用一个或几个键来表示,这种对每个汉字
用相应的按键进行的编码表示就称为汉字的“输入码”,又称外码。因此汉字的输入码的码
元(即组成编码的基本元素)是西文键盘中的某个按键。
2.字符集与汉字内码
汉字被输入到计算机内部后,就按照一种称为“内码”的编码形式在系统中进行存储、查
<!-- page: 60 -->
数据的机器级表示
找、传送等处理。对于西文字符,它的内码就是ASCⅡ码。对于汉字内码的选择,必须考虑
以下几个因素。
(1)不能有二义性,即不能和 ASCII码有相同的编码。
(2)要与汉字在字库中的位置有关系,以便于汉字的处理、查找。
(3)编码应尽量短。
为了适应计算机处理汉字信息的需要,1981年我国颁布了《信息交换用汉字编码字符
集·基本集》(GB 2312—80)。该标准选出6763个常用汉字,为每个汉字规定了标准代码,
以供汉字信息在不同计算机系统之间交换使用。这个标准称为国标码,又称国标交换码。
GB 2312 国标字符集由3部分组成:第一部分是字母、数字和各种符号,包括英文、俄
文、日文平假名与片假名、罗马字母、汉语拼音等共687个;第二部分为一级常用汉字,共
3755个,按汉语拼音排列;第三部分为二级常用字,共3008个,因为不太常用,所以按偏旁
部首排列。
GB 2312国标字符集中为任意一个字符(汉字或其他字符)规定了一个唯一的二进制代
码。码表由94行(十进制编号0~93行)、94列(十进制编号0~93列)组成,行号称为区
号,列号称为位号。每一个汉字或符号在码表中都有各自的位置,因此各有一个唯一的位置
编码,该编码用字符所在的区号及位号的二进制代码表示,7位区号在左,7位位号在右,共
14位,这14位代码就叫汉字的区位码。因此区位码指出了汉字在码表中的位置。
每个汉字的区号和位号各自加上32(即十六进制的 20H)后的相应二进制代码是其国
标码。在计算机内部,为了处理与存储的方便,汉字国标码的前后各7位分别用1字节来表
示,所以共需2字节才能表示一个汉字。因为计算机中的中西文信息是混合在一起进行处
理的,所以汉字信息如不予以特别标识,它与单字节的ASCIⅡ码就会混淆不清,无法识别。
这就是前面给出的第一个要考虑的因素。
为了解决这个问题,采用的方法之一,就是使表示汉字的两个字节的最高位(b?)总
等于1。这种双字节的汉字编码就是其中的一种汉字机内码(即汉字内码)。例如,汉
字“大”的区号是20,位号是83,因此区位码为1453H(0001010001010011B),国标码为