四. 十进制数的表示
人们日常使用和熟悉的是十进制,当使用计算机来处理数据时,在计算机外部看到的数据也基本上是十进制形式。那么十进制数在计算机上有几种表示方式?
- 二进制补码表示:这是一种最常见的表示形式,主要用于数值的计算。
- ASCII 码字符对应的
0~9
数字,这种方式将数字和字符进行了连接。 - 采用二进制编码的十进制数(BCD编码):以最简单的方式转为 2 进制,让机器识别。
BCD 编码
BCD 编码是采用二进制编码的十进制数。这个概念一听就很绕,但其实理解起来很简单。
BCD 编码主要分为两大类:
- 有权 BCD 编码:指十进制数的每位都由 4 个二进制位来表示,并且这 4 个二进制位的每位都有特定的权值。例如最常用的一种编码
8421 编码
。
故 16 可表示为 0001 0110
- 无权 BCD 编码:指表示十进制数每一位的4个二进制位没有特定的权,其与十进制能对应上是由人为规定的。例如四位典型格雷码:
五. 字符表示
1. 西文字符
西文由拉丁字母,数字,标识符以及一些特殊符号组成。字符不能直接在计算机内部进行处理,因而必须对其进行数字化编码。字符集有多种,每一个字符集的编码方式也多种多样,目前计算机中使用最广泛的西文字符集及其编码是 ASCII 码。
奇偶校验:
为了能检测和纠正内存软错误,我们需要一套方案来实现。
内存中最小的单位是比特,每 8 个比特作为一个字节。不带奇偶校验的内存中每个字节有 8 位。如果其某一位存储了错误的值,就会导致其存储的相应数据发生变化。而奇偶校验就是在每一字节(8位)之外又增加了一位作为错误校验位。
奇偶校验位是两种类型:
- 奇校验:指每个校验字节(9位)中
1
的个数必须奇数。如果前 8 位的个数已经是奇数,则校验位为 0,如果前 8 位的个数是偶数,则校验位为 1。 - 偶校验:指每个校验字节(9位)中
1
的个数必须偶数。如果前 8 位的个数已经是偶数,则校验位为 0,如果前 8 位的个数是奇数,则校验位为 1。
2. 汉字字符
计算机要对汉字信息进行处理,就必须就汉字本身进行编码,但汉字的总数超过 6 万,数量巨大。为了适应汉字系统各组成部分对汉字信息处理的不同需要,汉字系统必须处理一下集中汉字代码:输入码,内码,字模点阵码。
输入码
键盘是面向西文设计的,一个或两个西文字符对应一个按键。由于汉字字数多,无法使每个汉字与西文键盘上的一个键相对应,因此必须使每个汉字用一个或几个键来表示。这种对每个汉字用相应的按键进行的编码表示就称为汉字的“输入码”,又称“外码”。
内码
汉字被输入到计算机内部后,就按照一种称为“内码”的编码形式在系统中进行存储,查找,传送等处理。对于西文字符,他的内码就是 ASCII 码。
为了适应计算机处理汉字信息的需要,1981 年我国颁布了《信息交换用汉字编码字符集·基本集》(GB2312-80)。该标准选出 6737 个常用汉字,为每个汉字规定了标准代码,以供汉字信息在不同计算机系统之间交换使用。这个标准称为国标码,又称为国标交换码。
字模点阵码
经过计算机处理后的汉字,如果需要在屏幕上显示或打印机打印,则必须把汉字内码转换称人们可以阅读的方块形式。
每一个汉字的字形都必须预先存放在计算机内,一套汉字的所有字符的形状描述信息集合在一起称为字形信息库,不同的字体对应着不同的字库。在输出每一个汉字时,计算机都要先到字库中去找到它的字形描述信息,然后把字形信息送到相应的设备输出。
汉字的字形主要有两个描述方法:字模点阵描述和轮廓描述。
- 字模点阵描述是将字库中的各个汉字或其他字符的字形,有一个 其元素由“0”和“1”组成的方阵(如16x16)来表示,字符中有黑点的地方用“1”表示。
- 轮廓描述方法比较复杂,它把汉字画的轮廓用一组直线和曲线来勾画,记下每一直线和曲线的数学描述公式。
六. 数据的宽度和存储
1. 数据的宽度和单位
二进制数据的每一位是组成二进制信息的最小单位,称为比特(bit)。但二进制信息的计量单位是字节(byte),1byte = 8bit。
在考察计算机性能时,一个很重要的指标就是机器的字长。字长是指 CPU 内部用于整数运算的数据通路的宽度。CPU 内部数据通路是指 CPU 内部的数据流经的路径以及路径上的部件,主要时 CPU 内部进行运算的运算器尾数和通用寄存器宽度。
平时所说的“某种机器是 16 位机”,其中的 16 位就是指字长。
2. 数据的存储和排列顺序
任何信息在计算机中用二进制编码后,得到的都是一串 0/1 序列,每 8 位构成一个字节,不同的数据类型具有不同的字节宽度。一般用最低有效位和最高有效位来分别表示数的最低位和最高位。对于带符号数,最高位是符号位。
现代计算机基本上都采用字节编址方式,即对存储空间的存储单元进行编号时,每个地址编号中存放一个字节。计算机中许多类型数据由许多个字节组成。例如:int 和 float 型数据占用 4 字节,而程序中对每个数据只给定一个地址。例如,在一个按字节编制的计算机中,假定 int 型变量 i
的地址为 0800H
,i
的机器数为 01234567H
,这 4 个字节 01H
,23H
,45H
,67H
应该各有一个存储地址,那么,地址 0800H
对应 4 个字节中的哪个字节?这就是字节排列顺序问题。
- 大端方式排列:将数据的最高有效字节存放在小地址单元中,将最低有效字节存放在大地址单元中。上述的变量
i
的 4 个字节的存储地址为:0800H
:01H
,0801H
:23H
,0802H
:45H
,0803H
:67H
- 小端方式排列:将数据的最高有效字节存放在大地址单元中,将最低有效字节存放在小地址单元中。上述的变量
i
的 4 个字节的存储地址为:0800H
:67H
,0801H
:45H
,0802H
:23H
,0803H
:01H
七. 数据的基本运算
1. 按位运算和逻辑运算
按位运算的一个重要运用就是实现 掩码
操作,通过与给定的一个位模式进行按位与,可以提取所需要的位,然后可以对这些位进行“置1”,“置0”,“是否为1测试”,“是否为0测试”等,这里的位模式被称为 掩码
。例如表达式 0x0F & 0x8C
的运算结果为 0000 1100
,即 0x0C
。这里通过掩码 0x0F
提取了一个字节 0x8C
的底四位。
2. 移位
移位操作有 逻辑移位
和 算术移位
两种。
- 逻辑移位不考虑符号的问题,左移时高位移出,低位补0。右移时低位移出,高位补0。
- 算术移位考虑符号的问题,左移时高位移出,低位补0。右移时低位移除,高位补符号。
3. 位扩展和位截断
位扩展: 在进行数据类型转换时,如果一个短数向长数转换时,就要进行位扩展运算。进行位扩展后,数值应该保持不变。位扩展有两种方式:
- 0 扩展:0 扩展用于无符号数,只要在短的无符号数前面添加足够的 0 即可。
- 符号扩展:符号扩展用于补码表示的带符号整数,通过在短的带符号整数前面添加足够多的符号位来扩展。
位截断: 发生在长数转换位短数时,只要是截取长度的底 n 位。位截断可能会使数值发生变换。
4. 整数加减运算
在程序设计时通常把指针,地址等作为无符号整数,因而在进行指针或地址运算时需要进行无符号的加减运算。而其他情况下,通常都是带符号整数运算。无符号整数和带符号整数的加减运算电路完全一样。且由于有符号整数在机器中是用补码进行表示,故减法操作可以用加法来进行运算。
即:1 - 2 = 1 + (-2) = 0x0001
+ 0xfffe
= 0xffff
= -1(假设数据都为 short 型)
在进行整数运算时,其通用寄存器中的标志寄存器也随之存放相应的信息。如:
- 零标志寄存器(ZF):当结果为 0 时,为 1。
- 溢出标志寄存器(OF):若发生溢出时,则为1。两个相同符号的数相加才会发生溢出。
- 符号标志寄存器(SF):当结果为负数时,为 1。
- 进/借位标志寄存器(CF):两个数的补码相加时,若结果超出数据可表示的范围,则发生进/借位,为 1。
5. 浮点数加减运算
两个浮点数加减需要经历一下步骤:
- 对阶:对阶的目的是使两数的阶相等,以便尾数可以相加减。对阶的原则是:小阶向大阶看齐,即阶小的那个数的尾数右移。(有一个数的尾数表示会越小,可能在右移时会超出尾数的位数,导致溢出)
- 尾数加减:对阶后两个浮点数的阶相等,此时可以把对阶后的尾数相加减。
- 尾数规格化:
- 右规:若相加结果的整数部分超过一位,则需要将尾数向右移动到整数部分只有一位,此时可能会发生尾数溢出。
- 左规:若相加的结果的整数部分为 0,则需要将尾数向左移动到整数部分为 1。
- 尾数的舍入处理:在对阶和尾数右规时,可能会对尾数进行右移,为保证运算精度,一般将低位溢出的位保留下来,并让其参与中间过程的运算,最后再将运算结果进行舍入。舍入的方式有:
- 朝 +∞ 方向舍入:总是取数轴上右边最近可表示数。
- 朝 -∞ 方向舍入:总是取数轴上左边最近可表示数。
- 朝 0 方向舍入:直接截取所需位数,丢弃后面所有位。
- 阶码溢出判断:在进行尾数规格化和尾数舍入时,可能会对结果的阶码执行
+1
或-1
操作。因此必须考虑结果的阶溢出问题。- 尾数右规或舍入时,阶码需要
+1
。若阶码加一后全为 1,说明结果的阶比最大允许值127
还大,则发生“阶码上溢”。 - 尾数左规时,先阶码
-1
,若阶码减一后全为 0,说明结果的阶比最小允许值-126
还小,即结果位非规格话形式,此时应使结果的尾数不变,阶码全 0。
- 尾数右规或舍入时,阶码需要