2.2 主要内容提要
第 3 版 · OCR 辅助 · 原书检索 · 文字用于定位,公式与图表请回原页核验 · 本次导入快照
## 2.2 主要内容提要
### 1. 数据的表示
数据主要有数值数据与非数值数据两类。
数值数据是指在数轴上有对应的点、能比较大小的数,在计算机中有二进制数和十进制数两种表示形式。二进制表示有无符号整数、带符号整数和浮点数三类。无符号整数也称无符号数,用来表示指针、地址等正整数;带符号整数一般用补码表示;浮点数用来表示实数,现代计算机中多采用IEEE 754标准。十进制表示的主要是整数,需要用二进制对其进行编码,因此也称为BCD(Binary Coded Decimal)码,最常用的BCD码是8421码。
非数值数据是指在数轴上没有对应的点的数据。主要包括逻辑值、西文字符和汉字字符等。逻辑值只有两个状态取值,按位进行运算;西文字符多采用7位ASCII码表示;汉字字符有输入码、内码和字模码,汉字内码大多占2字节。
### 2. 数据的宽度
通常以字节(B)为基本单位表示,数据长度单位(如MB、GB、TB等)在表示数据容量和带宽等不同对象时所代表的大小不同。
### 3. 数据的排列
数据有大端和小端两种排列方式。大端方式以MSB所在地址为数据的地址,即给定地址处存放的是数据最高有效字节;小端方式以LSB所在地址为数据的地址,即给定地址处存放的是数据最低有效字节。
## 2.3 基本术语解释
机器数(computer word)
通常将数值数据在计算机内部编码表示的数称为机器数。机器数中只有0和1两种符号。
真值(natural number)
机器数真正的值(即原来带有正负号的数)称为机器数的真值。
数值数据(numerical data)
数值数据是指有确定的值的数据,在数轴上能找到其对应的点,可以比较其大小。确定一个数值数据的值有三个要素:进位记数制、定/浮点表示和数的编码表示。也就是说,给定一个数字序列,如果不说明这个数字序列是几进制数,小数点的位置在哪里,采用什么编码方式,那么这个数字序列的值是无法确定的。
<!-- page: 30 -->
非数值数据(non-numerical data)
非数值数据是指在数轴上没有确定的值的数据,像逻辑数据、西文字符、汉字字符等都是非数值数据。
基数(radix, base)
基数是指进位记数制的“底数”或“基”。例如,二进制数的基数是2,十进制数的基数为10,十六进制的基数为16。
无符号整数(unsigned integer)
当一个编码的所有二进位都用来表示数值时,该编码表示的就是无符号整数,也称为无符号数,可以看成正整数。常用于表示指针和地址等。
带符号整数(signed integer)
带符号整数是在计算机内部对正、负号进行编码了的整数,也称为有符号整数。
定点数(fixed-point number)
定点数是计算机中小数点固定在最左边或最右边的数,有定点整数和定点小数两种。定点整数的小数点总是约定在数的最右边,主要用来表示现实世界中的整数和浮点数中的指数。定点小数的小数点总是约定在数的最左边,主要用来表示浮点数中的尾数。
定点数的编码方式有原码、反码、补码和移码;浮点数的尾数一般用原码小数来表示;浮点数的指数一般用移码来表示;而反码很少被使用,只用在某些特殊场合。
浮点数(float-to-point number)
浮点数是计算机中可以指定小数点在不同位置的数。任意一个浮点数 $F$ 可写成 $F = M \times 2^{E}$ 的形式。这样,一个浮点数就可用两个定点数表示,$M$ 称为浮点数的尾数 (mantissa, significand),用一个定点小数来表示;$E$ 称为浮点数的指数或阶(exponent),用一个定点整数来表示。
原码(signed magnitude)
原码由符号位直接跟数值位构成,也称“符号-数值”表示法。它的编码规则是:正号“+”用符号位0表示,负号“-”用符号位1表示,数值部分不变。这种编码比较简单,但计算机处理不方便,20世纪50年代以后,就不用它来表示整数。现代计算机中,一般用它来表示浮点数的尾数,如IEEE 754标准。
反码(one's complement)
反码是一种对定点整数或定点小数进行二进制编码的编码方案。由于计算机处理反码没有补码方便,反码已很少被用了。
补码(two's complement)
补码编码规则是:正号“+”用符号位0表示,负号“-”用符号位1表示,正数的数值部分不变,负数的数值部分是“各位取反,末位加1”。这种编码较原码复杂,但由于它是一种模运算系统,计算机处理很方便。常用补码表示带符号整数。
变形补码(four's complement)
变形补码是一种双符号位补码,又称为“模4-补码”。双符号位可以用来检测定点整数是否发生溢出,左符号位为真正的符号位,右符号位用来判别是否溢出。采用“变形补码”进行溢出检测时的判断规则为“当结果的两个符号位不同时发生溢出”。双符号位通常用于保存运算过程中进到高位的数值部分。
<!-- page: 31 -->
## 移码 (excess notation, biased notation)
移码编码规则是:将真值加上一个偏置常数(bias)。因为在浮点数的加减运算中,要进行对阶操作,需要比较两个阶的大小。用移码表示阶码后,使得所有数的阶码都相当于一个正整数,比较大小时,就只要按高位到低位顺序比较就行了,因而,移码主要用来表示浮点数的阶码,可以简化阶码的比较过程。
## 单精度浮点数 (single precision floating point)
单精度浮点数是指 IEEE 754 标准规定的 32 位浮点数格式表示的浮点数。阶码用 8 位移码表示,偏置常数为 127,尾数用原码表示,规格化浮点数的最高位 1 隐含不表示,显式表示的尾数有 23 位,所以一共有 24 位尾数。
## 双精度浮点数 (double precision floating point)
双精度浮点数是指 IEEE 754 标准规定的 64 位浮点数格式表示的浮点数。阶码用 11 位移码表示,偏置常数为 1023,尾数用原码表示,规格化浮点数的最高位 1 隐含不表示,显式表示的尾数有 52 位,所以一共有 53 位尾数。
## 机器零 (machine “0”)
机器零用一种专门的位序列表示。例如,IEEE 754 单精度浮点数中,用 0000 0000H 表示 +0,用 8000 0000H 表示 -0。当运算结果出现阶码过小时,计算机将该数近似表示为“机器 0”。
## BCD 码
十进制数用二进制编码的形式表示称为 BCD(Binary Coded Decimal)码。
## 逻辑数据 (logic data)
逻辑数据用来表示命题的“真”和“假”,分别用 1 和 0 来表示。进行逻辑运算时,按位进行。
## ASCII 码
目前计算机中使用最广泛的西文字符集及其编码是美国标准信息交换码(American Standard Code for Information Interchange),简称 ASCII 码。
## 汉字输入码 (Chinese character input code)
汉字输入码是对每个汉字用一个标准键盘上按键的组合来表示的编码方式。一般分为数字编码(如区位码)、字音编码(如微软拼音、全拼)、字形编码(如五笔字型)和形音编码。
## 汉字内码 (Chinese character code)
汉字内码是用于汉字在计算机内部进行存储、查找、传输和处理而采用的编码方式,通常用两个字节表示一个汉字内码。
## 机器字长 (machine word length)
一个二进制位(bit,比特)是计算机内部信息表示的最小单位。而机器字长指的是特定计算机中 CPU 用于定点整数运算的数据通路的宽度,通常也就是 CPU 内定点数运算器和通用寄存器的位数。
## 编址单位 (addressing unit)
对主存单元编号时,具有相同编号的二进位数,主存单元的编号称为地址。通常的编址单位为 8,即字节。按字节编址时,编址单位为字节;按字编址时,编址单位为字。
<!-- page: 32 -->
字地址(word address)
按字节编址时,一个字可能占用几个内存单元,字地址就是这几个连续内存单元地址中的最小值。
最高有效位(Most Significant Bit, MSB)
最高有效位是一个二进制数中的最高位。例如,二进制数 1000 中的 1。
最低有效位(Least Significant Bit, LSB)
最低有效位是一个二进制数中的最低位。例如,二进制数 1110 中的 0。
最高有效字节(Most Significant Byte, MSB)
最高有效字节是一个二进制数中的最高字节。例如,二进制数 1111 1111 0000 0000 1111 0000 中的 1111 1111。
最低有效字节(Least Significant Byte, LSB)
最低有效字节是一个二进制数中的最低字节。例如,二进制数 1111 1111 0000 0000 1111 0000 中的 1111 0000。
大端方式(big endian)
采用字节编址方式时,一个多字节数据(如 int、float 等类型数据)将占用多个主存单元。大端方式下,将数据字的最低有效字节 LSB 存放在大地址单元中,即字地址是 MSB 所在单元的地址。
小端方式(little endian)
采用字节编址方式时,一个多字节数据(如 int、float 等类型数据)将占用多个主存单元。小端方式下,将数据字的最低有效字节 LSB 存放在小地址单元中,即字地址是 LSB 所在单元的地址。
边界对齐(boundary alignment)
边界对齐要求数据的地址是相应的边界地址。例如,按字节编址时,4 字节长数据的地址应该是 4 的倍数,即最末两位总是 00,2 字节长数据的地址总是 2 的倍数。
2.4 常见问题解答
1. 真值和机器数的关系是什么?
答:在计算机内部用二进制编码表示的数称为机器数,而机器数真正的值(即原来带有正负号的数)称为机器数的真值,所以,它们之间的关系就是同一个数据的两种不同表示形式。
2. 什么是编码?
答:编码是指用少量简单的基本符号对大量复杂多样的信息进行一定规律的组合。基本符号的种类和组合规则是信息编码的两大要素。例如,用 10 个阿拉伯数字表示数值,电报码中用 4 位十进制数字表示汉字,都是编码的典型例子。计算机内部处理的所有信息都是“数字化编码”了的信息。
3. 什么是数字化编码?
答:“数字化编码”就是对感觉媒体信息(如数值、文字、图像、声音、视频等信息)进行定时采样,将现实世界中的连续信息转换为计算机中离散的“样本”信息,然后对这些离散的
<!-- page: 33 -->
“样本”信息进行二进制编码。
## 4. 计算机内部为什么用二进制来编码所有信息?
答:主要有三方面的原因:
(1)二进制系统只有两个基本符号 0 和 1。所以,它的基本符号少,易于用稳态电路实现。
(2)二进制的编码、记数、运算等规则简单。
(3)二进制中的 0 和 1 与逻辑命题的“真”和“假”的对应关系简单,为计算机中实现逻辑运算和程序中的逻辑判断提供了便利的条件,特别是能通过逻辑门电路方便地实现算术运算。
## 5. 计算机内部用二进制表示信息,为什么还要引入八进制和十六进制?
答:计算机内部在进行信息的存储、传送和运算时,都是以二进制形式来表示信息的。但在屏幕上或书本上书写信息时,由于二进制信息位数多,阅读、记忆不方便,而十六进制、八进制和二进制的对应关系简单,又便于阅读、记忆和书写,所以引入十六进制或八进制,使得人们在开发、调试程序和阅读机器内部代码时,能方便地用八进制或十六进制来等价表示二进制信息。
## 6. 如何表示一个数值数据?计算机中的数值数据都是二进制数吗?
答:在计算机内部,数值数据的表示方法有以下两大类:
(1)直接用二进制数表示。分为无符号数和有符号数,有符号数又分为定点整数表示和浮点数表示。无符号数用来表示无符号整数(如地址等信息);定点整数用来表示带符号整数;浮点数用来表示实数。
(2)采用二进制编码的十进制数(即 BCD 码)来表示整数,BCD 码的编码方案很多,但一般都采用 8421 码(又称 NBCD 码)来表示。
因此,计算机中的数值数据虽然都用二进制来编码表示,但不全是二进制数,也有用十进制数表示的。因而,有些处理器的指令类型中,就有对应的二进制加法指令和十进制加法指令。
## 7. 为什么要引入无符号数表示?
答:因为有些情况下只要对正整数进行运算,且结果不出现负值,此时,可以用无符号数表示变量。例如,在进行地址或指针运算时可用无符号数。
## 8. 在高级语言程序中定义的 unsigned 型数据是怎么表示的?
答:unsigned 型数据就是无符号数,直接用二进制对数值进行编码得到的就是无符号数。
## 9. 为什么无符号数运算时结果可能会发生“溢出”?什么叫无符号数的“溢出”?
答:计算机的机器字长总是有限的,因而机器数的位数有限,使得可表示的数的个数有限。对于 $n$ 位二进制数,只能表示 $2^n$ 个不同的数,当运算结果超过 $n$ 位数时就可能发生溢出。
对于无符号数来说,计算机运算过程中一般保留低 $n$ 位,舍弃高位。这样,会产生以下两种结果:
(1)剩下的低 $n$ 位数不能正确表示运算结果。这种情况下,意味着运算的结果超出了计算机能表达的范围,有效数值达到了第 $n + 1$ 位,称此时发生了“溢出”现象。例如,对于
<!-- page: 34 -->
4位无符号数相加运算,当计算 $14 + 3$ 时就发生溢出,即 $1110 + C011 = 10001$ ,结果中第一位1是数值部分,这个1丢弃后结果就不对了。
(2) 剩下的低 $n$ 位数能正确表达计算结果,即高位的舍去并不影响其运算结果。例如,对于4位无符号数相减运算,当计算14-3时,用14加-3的补码来实现,即 $1110 + 1101 = 11011$ ,结果中第一位1不是数值部分,这个1丢弃后的结果是十进制的11,因此是正确的。
“对一个多于 $n$ 位的数丢弃高位而保留低 $n$ 位数”这样一种处理,实际上等价于“将这个多于 $n$ 位的数去除以2”,然后丢去商保留其余数”的操作。这种操作运算就是“模运算”。在一个模运算系统中,运算的结果最终都是丢弃高位而保留低位。所以,只要不是“溢出”(即只要真正的值不会进到第 $n + 1$ 位),结果就是正确的。这是模运算系统的特点。
## 10. 为什么现代计算机都用补码来表示整数?
答:和原码、反码相比,用补码表示定点整数时,有4个好处:①符号位可以和数值位一起参加运算;②补码可以实现模运算,即可用加法方便地实现减法运算;③零的表示唯一;④可以多表示一个最小负数。所以,现代计算机中都采用补码来表示定点整数。
## 11. $n$ 位二进制补码整数的模是多少?数的表示范围是什么?
答: $n$ 位二进制补码整数的模是 $2^{n}$ ,表示其运算结果只保留低 $n$ 位,多于 $n$ 位的高位部分取模后要被丢弃掉,其数值范围为 $-2^{(n-1)} \sim +2^{(n-1)} - 1$ 。
## 12. 在高级语言编程时定义的 short,int,long 型数据是怎么表示的?
答:int型数据就是定点整数,现代计算机一般用补码表示。int型数据的位数与运行平台和编译器有关,目前一般是32位或16位。long型数据和short型数据也都是定点整数,用补码表示,只是位数不同,分别是长整型和短整型数。
## 13. 在C语言程序中,关系表达式“ $-2147483648 = 2147483648U$ ”的结果为什么为“真”?
答:关系表达式“ $-2147483648 = 2147483648U$ ”的左边是负数,右边是正数,因此,左右两数看似不等,结果似乎应该为“假”。但是,在C语言中,如果在一个表达式中同时有unsigned int(无符号整数)类型和int(带符号整数)类型数据,那么,C编译器会隐含地将int型数据强制类型转换为无符号整数,因此,在上面的关系表达式运算中,左边的带符号整数 $-2147483648$ 对应的机器数10000000000000000000000000被解释成无符号整数,其值为 $2^{31}$ ,和右边的无符号整数 $2147483648U$ 的值完全相同,因而结果为“真”。
## 14. 定点整数在数轴上分布的点之间都是等距的吗?
答:是的。定点整数在数轴上的点总是在整数值上,即[…,-5,-4,-3,-2,-1,0,1,2,3,4,5,…],相邻数据间隔总是1。
## 15. 为什么要引入浮点数表示?
答:因为定点数不能表示实数,而且表数范围小,所以,要引入浮点数表示。
## 16. 为什么浮点数的阶(指数)要用移码表示?
答:因为在浮点数的加减运算中,要进行对阶操作,需要比较两个阶的大小。移码表示的实质就是把阶加上一个偏置常数,使得所有数的阶码都是一个正整数,比较大小时,就只要按高位到低位顺序比较就行了,因而,引入移码可以简化阶的比较过程。
## 17. 浮点数如何表示0?
答:用一种专门的位序列表示0,例如,IEEE 754单精度浮点数中,用00000000H表示
<!-- page: 35 -->
+0,用8000 0000H表示-0。当运算结果出现阶码过小时,计算机将该数近似表示为0,称为“机器0”。
18. 现代计算机中采用什么标准来表示浮点数?
答:早期的计算机各自采用不同的浮点数表示格式,因而,在不同计算机之间进行数据交换时,就会发生数据不统一的问题。所以,专门制定了IEEE 754标准用来规定计算机中的浮点数表示格式。现代计算机中都采用IEEE 754标准来表示浮点数。
19. 为什么浮点数要采用规格化形式表示?
答:为了使浮点数中能尽量多地表示有效位数,提高浮点数运算的精度,而且规格化形式具有唯一性。
20. 如何判断一个浮点数是否是规格化数?
只要看转换为真值后,其尾数的第一位是否一定是非零数。因此,对于原码编码的尾数来说,只要看尾数的数值部分第一位是否为1就行。
21. 浮点数表示的精度和数值范围取决于什么?
答:浮点数的精度取决于尾数的位数,而数值范围取决于阶码的位数。在浮点数总位数不变的情况下,阶码位数越多,则尾数位数越少。即表数范围越大,则精度越差(数变稀疏)。
22. 基数的大小对表数范围和精度有什么影响?
答:基数越大,则范围越大,但精度变低(数变稀疏)。
23. 在高级语言编程中,float 和 double 型数据是怎么表示的?
答:现代计算机用IEEE 754标准表示浮点数,其中32位单精度浮点数就是float型,64位双精度浮点数就是double型。
24. 在高级语言编程中,long double型数据是怎么表示的?
答:long double型数据的长度和格式随编译器和处理器类型的不同而有所不同。例如,Microsoft Visual C++ 6.0版本以下的编译器都不支持该类型,因此,用其编译出来的目标代码中long double和double一样,都是64位双精度;在IA-32上使用gcc编译器时,long double类型数据采用Intel x86 FPU的80位双精度扩展格式(1位符号位s、15位阶码e、1位显式首位有效位(explicit leading significand bit)j和63位尾数f)表示;在SPARC和PowerPC处理器上使用gcc编译器时,long double类型数据采用相应的128位双精度扩展格式(1位符号位s、15位阶码e和112位尾数f,采用隐藏位,故有效位数为113位)表示。
25. C语言程序中,为什么关系表达式“ $123456789 == (\text{int})(\text{float})123456789$ ”的结果为“假”,而关系表达式“ $123456 == (\text{int})(\text{float})123456$ ”和“ $123456789 == (\text{int})(\text{double})123456789$ ”的结果都为“真”?
答:首先应该明白,在C语言中,float类型对应IEEE 754单精度浮点数格式,即float型数据的有效位数只有24位(相当于有7位十进制有效位数);double类型对应IEEE 754双精度浮点数格式,有效位数有53位(相当于有17位十进制有效位数);int类型为32位整数,其有效位数为31位(最大数为2147483647)。
整数123456789的有效位数为9位,转换为float型数据后肯定发生了有效位数丢失,再转换为int型数据时,已经不是123456789了,所以,关系表达式“ $123456789 == (\text{int})(\text{float})123456789$ ”的结果为假。
<!-- page: 36 -->
数据改为 123456 后,有效位数只有 6 位,转换为 float 型数据后有效位数没有丢失,因而数据没变,再转换为 int 型数据时,还是 123456,所以,关系表达式“123456 = (int)(float)123456”的结果为真。
整数 123456789 的有效位数为 9 位,转换为 double 型数据后,不会发生有效位数丢失,再转换为 int 型数据时,还是 123456789,所以,关系表达式“123456789 = (int)(double)123456789”的结果为真。
26. 位数相同的定点数和浮点数中,可表示的浮点数个数比定点数个数多吗?
答:不是的。可表示的数据个数取决于编码所采用的位数。编码位数一定,则编码出来的数据个数就是一定的。n 位编码最多只能表示 2^n 个数,所以,对于相同位数的定点数和浮点数来说,可表示的数据个数应该一样多。但是,有时由于一个值可能有两个或多个编码对应,编码个数会有少量差异。
27. 如何进行 BCD 码的编码?
答:每位十进制数的取值可以是 0、1、2、……9 这十个数之一,因此,每一个十进制数位必须至少有 4 位二进制位来表示。而 4 位二进制位可以组合成 16 种状态,去掉 10 种状态后还有 6 种冗余状态,所以从 16 种状态中选取 10 种状态表示十进制数位 0~9 的方法很多,可以产生多种 BCD 码方案。大的方面可分为有权码和无权码两种。
有权码指表示每个十进制数位的 4 个二进制数位(称为基 2 码)都有一个确定的权。8421 码是最常用的十进制有权码;无权码指表示每个十进制数位的 4 个基 2 码没有确定的权。
28. 逻辑数据在计算机中如何表示?如何运算?
答:逻辑数据用来表示命题的“真”和“假”,分别用 1 和 0 来表示。进行逻辑运算时,按位进行。
29. 汉字的区位码、国标码和机内码有什么区别?
答:GB 2312 字符集由 94 行、94 列组成,行号称为区号,列号称为位号,各占 7 位,共 14 位,区号在左、位号在右,称为汉字的区位码,它指出了该汉字在码表中的位置。
汉字的国标码是将区号、位号各加上 32(即十六进制的 20H)后,再在前后各 7 位前加 0。
汉字的内码需要两个字节才能表示,可以在国标码的基础上产生汉字机内码,一般是将国标码的两个字节的第一位设置成“1”。
例如,已知一个汉字的国标码为 343AH,前后两个字节各减 32(20H) 得到区位码为 343AH - 2020H = 141AH,所以区号为 20(14H),位号为 26(1AH);机内码是将国标码的两个字节的最前面一位变为 1,因此,机内码为 B4BAH。
30. MSB(LSB)表示最高(低)有效字节还是最高(低)有效位?
答:MSB 的含义既可能是最高有效字节 (Most Significant Byte),也可能是最高有效位 (Most Significant Bit),具体表示哪一个含义要看上下文。同样,LSB 的含义既可能是最低有效字节 (Least Significant Byte),也可能是最低有效位 (Least Significant Bit)。
31. 有时用“字”表示数据的宽度,一个“字”到底有多少位?
答:除了用“位”(bit)和“字节”(Byte)来表示一个数据的宽度外,有时也用“字”(Word)来表示数据宽度的单位。不同的计算机,其“字”的长度和组成不完全相同,有的由 2 字节组
<!-- page: 37 -->
成,有的由4字节、8字节甚至16字节组成。