1.4 数据和数的表示

冯·诺伊曼模型清楚地将计算机定义为数据处理机,它接受输入数据、处理数据并输出相应的结果。但是,冯·诺伊曼模型并没有定义数据应该怎样存储在计算机中。下面来了解不同类型的数据是怎样以0和1序列的二进制模式存储在计算机内部的。

1.4.1 存储和组织数据

由于计算机是电子设备,所以最好的数据存储方式应该是电子信号,以电子信号的出现和消失的特定方式来存储数据。

日常主要使用的十进制数字是0~9这十种状态中的任何一个,但是不能(至少到目前为止)将这类信息直接存储到计算机内部,其他类型的数据(例如文本、图像、声音、视频等)也同样不能直接存储到计算机当中,除非将这类信息变换成只使用两种状态(0和1序列)的系统。

另一方面,尽管数据只能以一种形式(二进制模式)存储在计算机内部,但在计算机外部却可以表现为多种形式,如数字、文字、图像、音频和视频等。在存储到计算机中之前,数据被组织成许多小的单元,再由这些小的单元组成更大的单元等等。

1.4.2 计算机内部的数据

数据往往是多种类型的混合。例如,银行主要处理数字,但它也需要以文本形式存储客户的名字;图像则通常是图形和文本的混合。最有效的解决方法就是采用统一的数据表示法。所有计算机外的数据类型都采用统一的数据表示法,经过转换后存入计算机,当数据从计算机输出时再还原回来。这种通用的格式称为位模式。

1.位。bit,二进制数字,是存储在计算机中的最小数据单位,即0或1。“位”代表设备的某一状态,这些设备只能处于两种状态中的某一种状态。例如,开关合上或者断开。按惯例用1表示合上状态,用0表示断开状态。电子开关能表示位,换句话说,开关能存储一个位的信息。现在,计算机使用各种各样的两态设备来存储数据。

2.位模式。由于要存储更大的数、文本、图形等,单个“位”并不能解决数据表示问题。为了表示数据的不同类型,可以使用“位模式”,它是一个0和1的序列。例如:1000101010111111展示了由16个位组成的位模式。这就意味着,如果要存储一个由16个位组成的位模式。就需要16个电子开关。如果要存储1000个位模式,每个16位,那么就需要16000个开关。

计算机存储器仅仅将数据以位模式存储,至于位模式是数字类型、文本类型还是其他的数据类型,则由输入/输出设备或程序来解释。换句话说,当数据输入计算机时,它们被编码,当呈现给用户时,它们被解码,如图1-14所示。

978-7-111-49429-4-Chapter01-14.jpg

图1-14 位模式举例

3.字节。通常长度为8的位模式称为“字节”,这个术语同样被用作测量内存或其他存储设备的大小。例如,一台能存储100万位信息的计算机称其有1兆(M)字节的内存容量。

1MB=1024KB=1024×1024bit

1.4.3 表示数据

位模式可以用来表示不同类型的数据。

1.文本

位模式可以表示任何一个符号。例如,由4个符号组成的“BYTE”文本可采用4个位模式表示,每个模式定义一个符号:BYTE分别表示为1000010、1011001、1010100、1000101。

在一种语言中,位模式需要多少位来表示一个符号,取决于该语言集中有多少个不同的符号。位模式长度与符号数量的关系是个对数关系。例如,如果需要2个符号,位模式长度是1位(log22=1),即0、1;如果需要4个符号,位模式长度是2位(log24=2),即00、01、10和11,这些形式中的任何一种都可用来代表一个字符。同样,3位的位模式有8种不同的形式:000、001、010、011、100、101、110和111。

不同的位模式集合被设计用于表示文本符号,每一个集合被称为“代码”,表示符号的过程称为“编码”。常用的代码有。

(1)ASCII码:美国信息交换标准码,由美国国家标准协会(ANSI)开发。此代码使用7位表示每个符号,即可以定义27=128种不同的符号。

(2)扩展ASCII码:为了使每个位模式大小统一为1字节(8位),ASCII位模式通过在左边增加额外的0来进行扩充,使每一个模式都能很容易地恰好存入1字节大小的内存中。在扩展ASCII码中,第一个模式是00000000,最后一个是01111111。

(3)Unicode:为适应更大容量代码的需要,硬件和软件制造商们联合起来,共同设计了一种名为Unicode的代码,这种代码使用16位,能表示多达216=65536个符号。代码的不同部分被分配用于表示世界上不同语言的符号,其中还有部分代码被用于表示图形和特殊符号。Java语言就使用这种代码来表示字符。

微软公司的Windows使用了Unicode前256个字符的一个变化版本。

2.数

在计算机中,数是使用二进制系统,即位模式(一系列的0和1)来表示数。而像ASCII码这样的代码并没有用来表示数,这主要是因为数的表示方法不同于非数字形式的其他数据。

其他数据,如图形、图像和视频等的表示,将在本书第7章中进行详细介绍。

1.4.4 十六进制与八进制

数据存储在计算机中时是采用位模式表示的,但人们了解位模式时却很困难,一长串的0和1非常乏味且容易出错,这时,可以采用十六进制来加以简化。

十六进制以16为基数,这意味着有16个符号(十六进制数字),即0~9、A、B、C、D、E、F。十六进制数字与4个位对应,表1-1给出了位模式和十六进制数字间的关系。

将位模式转换成十六进制数,是将模式(从右边开始)组成每4个一组,找到与每组相对应的十六进制数字即可。例如,1111110011100100可表示成十六进制数的F C E 4。

表1-1 十六进制数字

978-7-111-49429-4-Chapter01-15.jpg

十六进制有两种写法。

1)在数的前面加小写或大写的x来代表十六进制。例如,xA34表示一个十六进制数。

2)将数字基数(16)作为表示法的下标。例如,A3416表示一个十六进制的值。

例1将二进制数110011100010转换成十六进制数。

解 将该二进制数分成每4位—组,即:110011100010,再转换成对应的十六进制数字,最后得到的十六进制数为xCE2。

例2 将十六进制数x24C转换成位模式。

解 将每一个十六进制数字转换成相对应的位模式,最后得到的位模式为00100100 1100。

另一种简化位模式的分组表示法是八进制法。八进制法以8为基数,这意味着有8个符号(八进制数字),即0~7。每个八进制数字对应于3个位。在数的前面加小写或大写的o(oct,在希腊语中表示8)来代表当前的表示方法为八进制。例如,o12表示一个八进制数。

1.4.5 十进制与二进制

第一个使用十进制计数系统的是8世纪的古埃及人,巴比伦人则改进了埃及人使用的记数系统,使得位置在记数系统中变得有意义。

在现代计算机中,十进制和二进制这两种计数系统占主导地位。十进制系统数的幂为10,因此,第一位为100,第二位为101,第三位为102,等等。例如,十进制的243可分解为:2×102+4×101+3×100

与十进制数为10不同,二进制系统数为2。例如,十进制数243转换为二进制数是11110011,同理可分解为:1×27+1×26+1×25+1×24+0×23+0×22+1×21+1×20

1.二进制数向十进制数转换

给出一个二进制数,将其每个二进制数字分别乘以它的权值,再将结果相加,即得到相应的十进制数。

例1将二进制数10011转换成对应的十进制数。

解 写出每位上的数值和相应的权值,然后将每位上的数值和对应的权值相乘,最后将结果相加,即得到相应的十进制数。即

100112=1×24+0×23+0×22+1×21+1×20=1×16+0×8+0×4+1×2+1×1=1910

2.十进制数向二进制数转换

采用除2取余法。以十进制数45为例,被底数2连除,得二进制101101,如图1-15所示。

例2 将十进制数35转换成相对应的二进制数。

解 用除2取余法,如图1-16所示。

978-7-111-49429-4-Chapter01-16.jpg

图1-15 十进制数45转换成二进制数

978-7-111-49429-4-Chapter01-17.jpg

图1-16 十进制数35转换成二进制数

1.4.6 整数表示法

整数即没有小数部分的完整数。例如,134是整数,而134.23不是整数。整数可以是正数或负数。负整数的范围是从负无穷到0,正整数是从0到正无穷。

为了高效地利用计算机的存储空间,人们设计开发了两种使用广泛的整数表示法,即无符号整数和有符号整数。有符号整数最常用的表示法是二进制补码。

1.无符号整数格式

无符号整数的范围介于0到正无穷大之间。通常,计算机都定义一个最大无符号整数的常量。这样,无符号整数的范围就介于0到该常量之间。而最大无符号整数取决于不同计算机的存储能力。无符号整数的范围可定义为0~(2N-1),这里N就是计算机中分配用于表示一个无符号整数的二进制位数。

存储无符号整数的过程可以简单地概括为以下步骤。

1)首先将整数变成二进制数。

2)如果二进制位数不足N位,则在二进制数的左边补0,使它的总位数为N位。

例1 将7存储在8位存储单元中。

解 首先将这个数转换为二进制数111。在该二进制数的左边加5个0,使总的位数为N(8)位,即得到00000111。再将该数存储到计算机的存储单元中。

无符号整数表示法可以提高存储的效率,因为不必存储整数的符号。这就意味着所有分配的位单元都可以用来存储数。只要无须用到负数,都可以用无符号整数表示法。无符号数一般用在计数、寻址等情况下。

2.二进制补码格式

二进制补码表示法是最普遍、最重要,也是应用最广泛的整数表示法,其整数表示范围是:

-(2N-1)~+(2N-1-1)

这里,N是计算机分配用于存储二进制补码整数的位数。

表1-2给出了现代计算机整数表示的一般范围。系统中只有一个0。

表1-2 二进制补码数的范围

978-7-111-49429-4-Chapter01-18.jpg

存储二进制补码需要以下步骤。

1)首先将数转换成二进制,符号被忽略。

2)如果二进制位数不足N位,在数的左边补0,直到总的位数为N。

3)如果符号为正,就不需再作变动。如果符号为负,则将最右边的所有0和首次出现的1保持不变,其余位取反。

在二进制补码表示法中,最左边的位定义为符号位。如果为0,数为正;如果是1,数为负。

例2 将+7用二进制补码表示法存储在8位存储单元中。

解 首先把数转换成二进制111,加上5个0使总的二进制位数为N(8)位,得到00000111。因为符号为正,不用再进行变化。

例3 将-40用二进制补码表示法存储在16位存储单元中。

解 首先把数转换成二进制101000,补上10个0使总的位数为N(16)位,得到0000000000101000。因为符号为负,所以,从右边的0到第一个l(包括1)不变,其余的换成它的反码形式。结果是:1111111111011000。

1.4.7 浮点数表示法

为了表示浮点数,数被分为两部分:整数部分和小数部分。例如,浮点数14.234就有整数部分14和小数部分0.234。

1.转换成二进制

把浮点数转换成二进制数,步骤如下。

1)把整数部分转换成二进制。

2)把小数部分转换成二进制。

3)在两部分之间加上小数点。

为把小数转换成二进制数,可以用连乘的方法,即“乘2取整法”。例如,把0.125转换成二进制数:将该数乘以2,得0.250,结果的整数部分(0)被提取出来,作为小数部分二进制数最左边的数字。接着继续用2来乘0.250得0.50。同样地,将结果的整数部分提取出来作为二进制数的下一位。如此反复,直到小数部分变成0或者达到你所能用到的位数。

例1 将小数0.875转换成二进制数。

解 将该数不断用2来乘,提取出整数部分作为二进制位。直到该数为0.0。得0.1112。

例2 将小数0.4转换成6位的二进制数(保留6位有效数字)。

解 将该数不断用2来乘,并提取出整数部分作为二进制位。在这个例子中,不可能恰好得到该小数正确的二进制表示,因为在乘的过程中原始小数再次出现,因此只需要取到题目所要求的6位就可以停止了。得0.0110012。

2.规范化

为了表示数71.3125(+1000111.0101),需要将符号、所有的位以及小数点的位置存储于内存中。这种方法虽然具有可行性,但使得数的运算变得困难。为此,需要浮点数标准表示法。解决的办法称为规范化,即移动小数点使小数点的左边只有一个“1”,即:

1.xxxxxxxxxxxxxxxxxx

为了表示这个数原始的值,将它乘以2e,这里e表示这个数的小数点所移动的位数:e为正数则左移,e为负数则右移。根据该数的正负将正负号加在最前面。表1-3给出了规范化的例子。

3.符号、幂和尾数

数在规范化之后只存储了这个数的三部分信息:符号、指数和尾数(小数点右边的位)。例如,+1000111.0101规范化后成为

978-7-111-49429-4-Chapter01-19.jpg

表1-3 规范化示例

978-7-111-49429-4-Chapter01-20.jpg

注意到小数点左边的l并没有存储,这种省略是可以理解的。

(1)符号。数的符号可以用一个二进制位来存储(0或者1)。

(2)指数。指数(2的幂)定义小数点移动的位数。幂可以为正也可以为负。

(3)尾数。尾数是指小数点右边的二进制数,它定义了数的精度。尾数作为无符号整数存储。