第2章 计算机基础知识
2.1 计算机中的数制与编码
数据是计算机处理的对象。在计算机内部,各种信息都必须经过数字化编码后才能被传送、存储和处理,而在计算机中采用什么数制,如何表示数的正负和大小,是学习计算机首先遇到的一个重要问题。二进制并不符合人们的使用习惯,但是计算机内部却采用二进制表示信息,其主要原因有以下4点。
1. 电路简单:计算机是由逻辑电路组成的,逻辑电路通常只有两个状态。例如,开关的接通与断开,电压电平的高与低等。这两种状态正好用二进制的0和1来表示。若采用十进制,则要求处理10种电路状态,这相对于两种状态的电路来说,是很复杂的。
2. 工作可靠:两种状态代表两种数据信息,数字传输和处理不容易出错,因而电路更加可靠。
3. 简化运算:二进制运算法则简单。
4. 逻辑性强:计算机工作原理是建立在逻辑运算基础上的,逻辑代数是逻辑运算的理论依据。二进制只有两个数码,正好代表逻辑代数中的“真”与“假”。
2.1.1 数制及转换方法
人们最常用的数是十进制数,计算机中为了计算和存储方便,使用二进制数,人们也使用八进制和十六进制数,下面介绍这几种数制及其转换。
1. 几种数制的表示
为了方便起见,使用不同的后缀表示不同的数制。
二进制——后缀B,例如11010011B
八进制——后缀Q,例如7321Q
十进制——后缀D或省略,例如732.15
十六进制——后缀H,例如87FFH
十进制数的基数为10,有十个不同的数字符号:0,1,2,…,9,遵循“逢十进一”原则。一般地,任意一个十进制数N都可以表示为:
上式是十进制按权展开式。式中,10称为十进制数的基数,i表示数的某一位,10i称为该位的权,Ki表示第i位的数码,它可以是0~9中的任意一个数,由具体的数N确定。m和n为正整数,n为小数点左边的位数,m为小数点右边的位数。表达式可以推广到任意进位记数制。
二进制数的基数为2,有两个不同的数字符号:0和1,遵循“逢二进一”原则。一般地,任意一个二进制数N都可以表示为:
八进制数的基数为8,有8个不同的数字符号:0,1,2,…,7,遵循“逢八进一”原则。一般地,任意一个八进制数N都可以表示为:
十六进制数的基数为16,有16个不同的数字符号:0~9,A,B,C,D,E,F,遵循“逢十六进一”原则。一般地,任意一个十六进制数N都可以表示为:对于十六进制,R=16,K为16个数码中的任意一个,逢十六进一。
综上可见,上述几种进位制有以下共同点:
(1)每种进位制都有一个确定的基数R,每一位的系数K有R种可能的取值。
(2)按“逢R进一”方式计数,在混合小数中,小数点左移一位相当于乘以R,右移一位相当于除以R。
2. 数制间的转换
(1)二、八、十六进制数转换为十进制数
二、八、十六进制数转换为十进制数时,该数每位上的数字与其对应的权值乘积之和,便是其对应的十进制值。
例如:
(1110.01)2 =1×23+1×22+1×21+0×20+0×2-1+1×2-2 =(4.25)10
(170)8 =1×82+7×81+0×80 =(120)10
(B2F)16 =11×162+2×161+15×160=(2863)10
(2)十进制转换成二、八、十六进制数
十进制数转换成二、八、十六进制数时,需要把整数部分与小数部分分别转换,转换整数部分要用基数去除,转换小数部分要用基数去乘,然后拼接起来。
转换十进制数整数部分的算法如下。
① 用其他数制的基数除十进制数。
② 保存余数(最先得到的余数为最低有效位)。
③ 重复①②,直到商为零。
例如:十进制数124转化二进制数(124)10=(Kn-1…K1K0)2
按权展开为:
(124)10=Kn-1×2n-1+…+K1×21+K0×20
而124÷2的余数正好是0,因此K0=0。将62继续除以2,余数正好是0,因此K1=0。用类似的方法继续除以2,可将Kn-1…K0都确定下来。因而转换结果为:
(124)10=(11111100)2
转换十进制数整数部分的算法如下。
① 用其他数制的基数乘十进制数。
② 保存结果的整数(最先得到的整数为最高有效位)。
③ 重复①②,直到小数为零。
例如:将十进制数0.8125转换为二进制小数。
设:(0.8125)10 =(0.K-1K-2…K-m)2,展开为:(0.8125)10=K-1×2-1+K-2×2-2+…+K-m×2-m
将上式两边同乘以2,得到:
1.625=K-1+K-2×2-1+…+K-m×2-m+1
整数:1=K-1
小数:0.625=K-2×2-1+K-3×2-2+…+K-m×2-m+1
上式继续乘以2,有:
1.25=K-2+K-3×2-1+…+K-m×2-m+2
整数:1=K-2
小数:0.25=K-3×2-1+…+K-m×2-m+2
以此类推,可逐个求出K-1K-2…K-m的值。
所以转换结果为:(0.8125)10=(0.1101)2
如果一个数既有小数又有整数,则应将整数部分与小数部分分别进行转换,然后用小数点将两部分连起来,即为转换结果。
例如:
所以:(3.125)10=(11.001)2
(3)二进制与八进制、十六进制的相互转换
由于8=23,16=24,因此二进制与八进制或十六进制之间的转换就很简单。将二进制数从小数点位开始,向左每3位产生一个八进制数字,不足3位的左边补零,这样得到整数部分的八进制数;向右每3位产生一个八进制数字,不足3位右边补0,得到小数部分的八进制数。同理,将二进制数转换成十六进制数时,只要按每4位分割即可。
例如:(100100.101001)2=(44.51)8=44.51Q
=(00100100.10100100)2=(24.A4)16=24.A4H
八或十六进制要转换成二进制,只需将八或十六进制数分别用对应的3位或4位二进制数表示即可。
2.1.2 计算机中数的表示及运算
1. 数的二进制码
我们知道,数是有正有负的,带符号数的习惯表示方法是在数值前用“+”号表示正数,“-”号表示负数。计算机只能识别0和1,对数值的符号也不例外,数的符号在机器中也要数码化,对于带符号的数,在计算机中,通常将一个数的最高位作为符号位,最高位为0,表示符号位为正;最高位为1,表示符号位为负。带有数码化的符号数称为机器数。机器数的最高位是其符号位,0表示正数,1表示负数。在计算机内,数有3种表示法:原码、反码和补码。
(1)原码
以最高位为0表示正数,1表示负数,后面各位为其数值,这种数的表示法称为原码。
原码的几个特点如下。
① 数值部分即为该带符号数的二进制值。
② “0”有+0和-0之分,若字长为八位,则:
(+0)原=00000000
(-0)原=10000000
③ 8位二进制原码能表示的数值范围为:
01111111~11111111,即+127~-127。
那么,对于n位字长的计算机来说,其原码表示的数值范围为2n-1-1~-2n-1+1。
(2)反码
正数的反码与其原码相同,最高位为0表示正数,其余位为数值位。负数的反码是其对应的正数连同符号位按位取反求得。
二进制反码的特点如下。
① “0”有+0和-0之分。
② 8位二进制反码所能表示的数值范围为+127~-127,一般地,对于n位字长的计算机来说,其反码表示的数值范围为+2n-1-1~-2n-1+1。
③ 8位带符号的数用反码表示时,若最高位为“0”(正数),则后面的7位即为数值;若最高位为“1”(负数),则后面7位表示的不是此负数的数值,必须把它们按位取反,才是该负数的二进制值。
(3)补码
正数的补码与其原码相同。负数的补码为其反码加1,即在其反码的最低位上加1得到。
二进制补码的几个特点如下。
① [+0]补=[-0]补=00000000,即无+0和-0之分。
② 正因为补码中没有+0和-0之分,所以8位二进制补码所能表示的数值范围为+127~-128;同理可知,n位二进制补码表示的范围为+2n-1-1~-2n-1。在原码、反码和补码三者中,只有补码可以表示-2n-1。
③ 一个用补码表示的二进制数,当为正数时,最高位(符号位)为“0”,其余位即为此数的二进制值;当为负数时,最高位(符号位)为“1”,其余位不是此数的二进制值,必须把它们按位取反,且在最低位加1,才是它的二进制值。
2. 二进制码之间的转换运算
我们知道了计算机可以有三种编码方式表示一个数。对于正数因为三种编码方式的结果都相同:[+1] = [00000001]原 = [00000001]反 = [00000001]补,所以不需要过多解释。但是对于负数:[-1] = [10000001]原 = [11111110]反 = [11111111]补,可见原码、反码和补码是完全不同的。
既然原码才是被人脑直接识别并用于计算表示方式,为何还会需要有反码和补码呢?首先,因为人脑可以知道第一位是符号位,在计算的时候我们会根据符号位,选择对真值区域的加减。但是对于计算机,加减乘除是最基础的运算,要设计得尽量简单。计算机辨别“符号位”显然会让计算机的基础电路设计变得十分复杂。于是人们想出了将符号位也参与运算的方法。我们知道,根据运算法则减去一个正数等于加上一个负数,即:1-1 = 1 +(-1)= 0,所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了。于是人们开始探索将符号位参与运算,并且只保留加法的方法。
例如,计算十进制的表达式:1-1=0,可以写成:
如果用原码表示,让符号位也参与计算,显然对于减法来说,结果是不正确的,这也就是为何计算机内部不使用原码表示一个数。为了解决原码做减法出现的问题,产生了反码:计算十进制的表达式:
发现用反码计算减法,结果的真值部分是正确的,而唯一的问题其实就出现在0这个特殊的数值上。虽然人们理解上+0和-0是一样的,但是0带符号是没有任何意义的。而且会有[00000000]原和[10000000]原两个编码表示0。于是补码的出现,解决了0的符号以及两个编码的问题:
这样0用[00000000]表示,而以前出现问题的-0则不存在了。而且可以用[10000000]表示-128:
-1-127的结果应该是-128,在用补码运算的结果中,[10000000]补就是-128。但是注意因为实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示(对-128的补码表示[10000000]补算出来的原码是[00000000]原,这是不正确的)。
使用补码,不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数。这就是8位二进制使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围为[-128, 127]的原因了。
2.1.3 计算机中的常用编码
计算机编码指电脑内部代表字母或数字的方式,常见的编码方式有:ASCII编码、GB2312编码(简体中文)、GBK、BIG5编码(繁体中文)、ANSI编码、unicode、utf-8编码等。编码单位最小的单元是位(bit),接着是字节(Byte),一个字节=8位,英文表示是1 Byte=8 bits,机器语言的单位为Byte。1KB=1024 Byte,1MB=1024KB,1GB=1024MB,1TB=1024GB。
1. BCD码
BCD码(Binary-Coded Decimal)亦称二进码十进数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数码。是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了4个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷地进行。
由于十进制数共有0,1,2,…,9十个数码,因此,至少需要4位二进制码来表示1位十进制数。4位二进制码共有24=16种码组,在这16种代码中,可以任选10种来表示10个十进制数码。
(1)BCD码分类
BCD码可分为有权码和无权码两类:有权BCD码有8421码、2421码、5421码,其中8421码是最常用的;无权BCD码有余3码,余3循环码等。
① 8421码:8421 BCD码是最基本和最常用的BCD码,它和4位自然二进制码相似,各位的权值为8,4,2,1,故称为有权BCD码。和4位自然二进制码不同的是,它只选用了4位二进制码中前10组代码,即用0000~1001分别代表它所对应的十进制数,余下的六组代码不用。
② 5421码和2421码:5421 BCD码和2421 BCD码为有权BCD码,它们从高位到低位的权值分别为5,4,2,1和2,4,2,1。这两种有权BCD码中,有的十进制数码存在两种加权方法,例如,5421 BCD码中的数码5,既可以用1000表示,也可以用0101表示;2421 BCD码中的数码6,既可以用1100表示,也可以用0110表示。这说明5421 BCD码和2421 BCD码的编码方案都不是唯一的。
③ 余3码;余3码是8421 BCD码的每个码组加3(即0011)形成的,常用于BCD码的运算电路中。
④ Gray码:Gray码也称循环码,其最基本的特性是任何相邻的两组代码中,仅有一位数码不同,因而又叫单位距离码。
表2-1 常用BCD码
(2)BCD码的特点
① 8421码直观,好理解。
② 5421码和2421码中大于5的数字都是高位为1,5以下的高位为0。
③ 余3码是8421码加上3,有上溢出和下溢出的空间。
④ Gray码相邻的2个数只有一位不同。
2. ASCII码
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写),以及0和1等数字还有一些常用的符号(例如*、#、@等),在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。
美国标准信息交换代码是由美国国家标准学会(American National Standard Institute,ANSI)制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于20世纪50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization,ISO)定为国际标准,称为ISO 646标准,适用于所有拉丁文字字母。
ASCII码的表述方式如下。
ASCII码使用指定的7位或8位二进制数组合来表示128或256种可能的字符。标准ASCII码也叫基础ASCII码,使用7位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0到9、标点符号,以及在美式英语中使用的特殊控制字符。
0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10和13分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
32~126(共95个)是字符(32是空格),其中48~57为0到9这10个阿拉伯数字。65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII码允许将每个字符的第8位用于确定附加的128个特殊符号字符、外来语字母和图形符号。
表2-2 ASCII表
3. 汉字编码
计算机只识别由0、1组成的代码,计算机在我国应用时,要能够输入、处理和输出汉字。显然,汉字在计算机中也只能用若干位的二进制编码来表示。ASCII码是英文信息处理的标准编码,汉字信息处理也必须有一个统一的标准编码。我国国家标准局于1981年5月颁布了《信息交换用汉字编码字符集——基本集》,代号为GB2312-80,共对6763个汉字和682个图形字符进行了编码,其编码原则为:汉字用两个字节表示,每个字节用七位码(高位为0);国家标准将汉字和图形符号排列在一个94行94列的二维代码表中;每两个字节分别用两位十进制编码,前字节的编码称为区码,后字节的编码称为位码,此即区位码。如“保”字在二维代码表中处于17区第3位,区位码即为“1703”。
该标准编码字符集共收录汉字和图形符号7445个,包括以下几种。
① 一般符号202个:包括间隔符、标点、运算符,单位符号和制表符等。
② 序号60个:包括1.~20.、(1)~(20)、①~⑩和(-)~(+)等。
③ 数字22个:0~9和I~XII。
④ 英文字母52个:大、小写各26个。
⑤ 日文假名169个:其中平假名83个,片假名86个。
⑥ 希腊字母48个:其中大、小写各24个。
⑦ 俄文字母66个:其中大、小写各33个。
⑧ 汉语拼音符号26个。
⑨ 汉语注音字母37个。
⑩ 汉字6763个:分两级,第一级汉字3755个,第二级汉字3008个。
显然,汉字机内码的每个字节都大于128,这就解决了与西文字符的ASCII编码冲突的问题。