计算机科学导论(2):数据存储

原文链接:计算机科学导论(2):数据存储 | 远行的舟

数据包括数字、文本、音频、图像和视频,它们都以bit, binary digit)的形式存储在计算机中,binary digit 是二进制数的意思。由于各种类型的数据最终都以数字的形式存储在计算机中,所以我们首先阐述计算机是如何存储整数和实数的。

2.1 数字的存储

计算机存储整数的方法为定点表示法fixed-point representation)中的无符号表示法unsigned representation)和补码表示法complement representation),计算机存储实数的方法则为浮点表示法float-point representation),浮点表示法又内在地包含了定点表示法中的符号加绝对值表示法sign-and-magnitude representation),下面将逐一介绍上述各种方法。

2.1.1 定点表示法

所谓定点表示法,就是指小数点位置固定的表示法,它通常用来表示整数,有时也用于表示实数。对于整数而言,小数点固定在最右边且不被存储,图 2-1 展示了整数的定点表示法。定点表示法包括:无符号表示法、符号加绝对值表示法以及补码表示法。

图 2-1 整数的定点表示法

无符号表示法用于无符号整数的存储,对于用不到负整数的情况,无符号表示法由于不必存储符号而提高了存储的效率,它广泛应用于计数中数字的存储、寻址中存储单元地址的存储以及文本图像音频视频的存储。若计算机中分配给无符号整数的位数为 n n n,则计算机能存储的无符号整数范围为 0 , 1 , 2 , ⋯   , 2 n − 1 0,1,2,\cdots ,2^{n}-1 0,1,2,,2n1,此时如果保存大于 2 n − 1 2^{n}-1 2n1 的整数就会出现溢出overflow)的现象,计算机将丢掉该整数左边的部分位而只保留最右边的 n n n 位,图 2-2 展示了当 n n n 为 4 时,无符号整数的溢出情况。

图 2-2 无符号整数的溢出

符号加绝对值表示法虽然是定点表示法,却很少用来表示整数,而主要用于部分实数或者音频采样数据的存储。它将无符号整数的有效范围 0 , 1 , 2 , ⋯   , 2 n − 1 0,1,2,\cdots ,2^{n}-1 0,1,2,,2n1 分成两个相等的子范围,前半部分用来表示非负整数、后半部分用来表示非正整数,在这种表示法中存在两个 0,其最左位用于定义整数符号,0 为正,1 为负。若计算机中分配给有符号整数的位数为 n n n,则计算机能存储的有符号整数范围为 − ( 2 n − 1 − 1 ) , ⋯   , − 1 , 0 , 1 , ⋯   , 2 n − 1 − 1 -\left (2^{n-1}-1 \right),\cdots ,-1,0,1,\cdots ,2^{n-1}-1 (2n11),,1,0,1,,2n11,一旦超出这个范围便会发生溢出现象。图 2-3 展示了当 n n n 为 4 时,符号加绝对值表示法所能表示的所有有符号整数,紧接着的图 2-4 则展示了当 n n n 为 4 时符号加绝对值表示法的溢出情况。

图 2-3 符号加绝对值表示法

图 2-4 符号加绝对值表示法的溢出

补码表示法是为几乎所有计算机所采用的有符号整数的表示方法,补码是一种运算,它从原码右边开始复制位直到原码位中第一次出现 1,在复制这个 1 后,对于原码中剩余的其他位取反码运算,即原码位为 1 时补码对应位为 0,原码位为 0 时补码对应位为 1,图 2-5 展示了取整数 00110100 补码的运算过程。所谓补码表示法即是对非负整数以其原码存储,对负数则取其补码存储,并规定最左位为符号位,以 0 为正,以 1 为负。图 2-6 展示了当存储位数 n n n 为 4 时补码表示法所能表示的所有有符号整数,与符号加绝对值表示法相比,它的表示范围要更大,为 − 2 n − 1 , ⋯   , − 1 , 0 , 1 , ⋯   , 2 n − 1 − 1 -2^{n-1} ,\cdots ,-1,0,1,\cdots ,2^{n-1}-1 2n1,,1,0,1,,2n11. 图 2-7 则展示了补码表示法的溢出情况。

图 2-6 补码表示法

图 2-7 补码表示法的溢出

至于人们为什么要费劲巴力地弄出一个补码运算来表示有符号整数,我们将在下一章中阐述。在那里,在有关数据运算的内容中,你将看到补码表示法给运算带来的巨大便利。

2.1.2 浮点表示法

浮点表示法用于实数的存储,一个数字的浮点表示法由符号S, sign)、指数E, exponent)和尾数M, mantissa)三部分组成。其中指数部分表示小数点移动的位数,采用余码excess code)的方式存储,尾数则是小数点右边的二进制数,它采用无符号表示法存储,小数点左边仅留一位、不进行存储且其取值由指数部分决定。

指数部分是有符号整数,按理来说可以采用补码表示法存储,缘何又要引进新的余码表示法呢?这是因为在余码系统中的所有整数都是正数,而这为不同浮点数之间大小的比较和运算提供了方便。若 n n n 为指数位数,则所谓余码表示法就是将一个偏移量 2 n − 1 − 1 2^{n-1}-1 2n11 添加到每个数中,这样原来的负数和正数均变为了无符号的正数。图 2-8 展示了当指数位数为 4 时的余码表示法。

图 2-8 余码表示法

IEEE 二进制浮点数算术标准(ANSI/IEEE Std 754-1985)规定了四种表示浮点数的方式:单精度(32 位,符号 1 位,指数 8 位,尾数 23 位)、双精度(64位,符号 1 位,指数 11 位,尾数 52 位)、延伸单精度(43位以上,很少使用)与延伸双精度(79位以上,通常以80位实现)。另外 IEEE 对浮点数表示还有以下几点规定:

  • 当指数部分为 0 时,小数点左边一位恒为 0,否则恒为 1,后者称为规约数,前者称为非规约数且其小数点移动位数为指数部分的取值减去 1.
  • 当指数部分为 0 且尾数部分也为 0 时,该数表示 0.
  • 当指数部分为 2 n − 1 2^{n}-1 2n1 且尾数部分为 0 时,该数表示 ±   ∞ \pm \,\infty ±.
  • 当指数部分为 2 n − 1 2^{n}-1 2n1 且尾数部分不为 0 时,该数表示 N a N NaN NaNNot a Number).

图 2-9 展示了十进制数 -2104378.75 在 IEEE 单精度标准下的浮点表示法,表 2-10 则展示了在 IEEE 单精度标准下计算机所能存储的各种极值。

图 2-9 单精度标准下 -2104378.75 的浮点表示法

表 2-10 单精度标准下的各种极值

至此,我们已经知道了在计算机中整数和实数是如何存储的,我们或许还有很多疑问,疑问于缘何计算机要以这样的方式而不以另外的方式存储这些数字。亲爱的读者,在我敲下这些文字时,我的心中与你有着同样的疑惑,但我相信,先贤们制定这样的标准而不是那样的标准,选择这样的方式而不是那样的方式,自有其道理所在。现在暂且让我们放下这些或许还需要许许多多其他知识才能求得答案的谜团,来看一看聪明的人们是如何将文本、音频、图像、视频这些看似与数字毫不相干的信息转化为数字(我们称这一过程为编码)进而使得它们能够在计算机中存储的。

2.2 文本的存储

在任何语言中,文本text)都可以看作是一系列字符的组合,将文本数字化只需要将语言中的字符集与数字一一对应起来即可。进一步,在计算机中,就是要将语言字符集与位模式bit pattern)即位串一一对应起来。若语言字符集中字符数量为 n n n,则所需位模式的长度为 log ⁡ 2 n \log_{2}n log2n ,表 2-11 给出了部分字符数量与位模式长度的关系。

表 2-11 字符数量与位模式长度的关系

由于人类语言的多样性与差异性,人们先后制定了许许多多不同的文本编码规则,例如:由美国国家标准协会(ANSI)制定的美国信息交换标准码ASCII)、基于 Unicode 字符集UTF-8 编码(8-bit Unicode Transformation Format),基于 Unicode 字符集或通用字符集UCS, Universal Character Set)的 UTF-16/UCS-2 编码和 UTF-32/UCS-4 编码等等。

ASCII 最初采用 7 位表示一个字符,因而总共能表示 128 个字符,后来 IBM 在此基础上扩展,用 8 位表示一个字符,扩展后的 ASCII 总共能表示 256 个字符。256 个字符的容量对于英文世界而言已完全足够,但对于动辄几万个字的中文世界而言,这样的容量实在有点捉襟见肘、杯水车薪。后来中国人弄出了自己的编码方案:针对简体中文的 GB2312 和针对繁体中文的 Big5,世界上许多其他国家也弄出了针对自己国家语言的编码方案,于是制定一个统一的包容世界上所有语言的字符集并基于这个统一的字符集制定编码规则就成了人们必须面对的问题。在这样的大背景下,Unicode、UCS,这两个如今已经可以表示多达上亿个符号的字符集,应运而生。Unicode 由多语言软件制造商组成的统一码联盟提出,而 UCS国际标准化组织ISO)提出,二者于 1991 年前后实现兼容并为创建一个单一编码表而协同工作。从 Unicode 2.0 开始,Unicode 采用了与 ISO 10646-1 相同的字库和字码;ISO 也承诺,ISO 10646 将不会替超出 10FFFF 的 UCS-4 编码赋值,以使得两者保持一致。两个项目目前仍都存在,并独立地公布各自的标准。但统一码联盟和 ISO 都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。下面我们将详细介绍 UTF-8 编码以及与其紧密相关的 UTF-16/UCS-2 编码和 UTF-32/UCS-4 编码,通过对这三种编码规则各自优缺点的比较,我们将会知道:为什么是 UTF-8 而不是其他编码成了如今网络时代文本信息交换的通用规则。

UTF-8 是一种可变字节长度的编码规则,表 2-12 向我们展示了这一编码规则。

表 2-12 UTF-8 编码

表中 UTF-8 编码一列中,0 和 1 是固定不动的,x 则是 Unicode/UCS 字符对应二进制数的存储位。在字符编码笔记:ASCII,Unicode 和 UTF-8一文中,阮一峰老师将 UTF-8 的编码规则总结如下:

UTF-8 的编码规则很简单,只有二条:
1.对于单字节的符号,字节的第一位设为 0,后面 7 位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2.对于 n n n 字节的符号( n > 1 n > 1 n>1),第一个字节的前 n n n 位都设为 1,第 n + 1 n + 1 n+1 位设为 0,后面字节的前两位一律设为 10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

相比 UTF-8 而言,UTF-16/UCS-2UTF-32/UCS-4 编码规则更加简单,在 UTF-16/UCS-2 中,规定每一个字符都用 2 个字节存储,而在 UTF-32/UCS-4 中,则规定每一个字符都用 4 个字节存储。不过这两种编码规则还涉及到字节序byte order)的问题,以 UTF-16/UCS-2 为例,汉字 “严” 的 Unicode 码为 4E25,如果先存储字节 4E,后存储字节 25,这种存储字节的顺序称为大头方式Big Endian),相反如果先存储字节 25,再存储字节 4E,则称为小头方式Little Endian)。由于 UTF-8 有固定的 0 和 1 作为标记,因此计算机识别起来并不困难,但 UTF-16UTF-32 不仅没有区分二者的标记也没有区分不同字节序的标记,因此人们引入了字节序标记BOM, Byte Order Mark),即在每一个文件的最前面加入的一个表示编码顺序和编码方式的字符。表 2-13 列出了 UTF 系列编码对应的字节序标记。

表 2-13 UTF 系列编码的字节序标记

上面我们了解了 UTF 系列编码的规则,下面我们来讨论这三种编码方式的优劣。UTF-16UTF-32 存在以下几点问题:

  • 由于规定统一采用 2 个字节存储字符,UTF-16 能表示的字符数量仅有 6 万多,而 Unicode 5.0 收录的字符就已经达到 99024 个,远远超过了这个范围。UTF-32 虽然克服了这一困难,但所有字符均采用 4 个字节存储,是对存储资源的一种巨大浪费
  • 由于 UTF-16/UTF-32 存在字节序问题,在进行信息交换时,如果事先未经协商就会导致乱码,如果事先已经协商但双方一个采用大头方式一个采用小头方式的话,就必须有一方进行转换,信息交换的效率将因此而降低
  • UTF-16/UTF-32 而言,如果发生局部的字节错误,特别是丢失或增加部分字节,此时计算机并不会跳过这些错误,依旧会按照两个字节为一个单位的方式存储和读取文本,这极有可能导致后续字符全部错乱

当然 UTF-16/UTF-32 也有其优点,由于每一个字符的位数相同,对使用这些编码格式存储的文本计算其长度、执行索引操作时要更快。并且对于中文字符占多数的文本的存储而言,UTF-16 的方式比 UTF-8 所需的存储空间要小得多,因为在 UTF-8 编码规则下,许多汉字的存储需要 3 个字节。UTF-8 编码不存在上述缺点,它能表示的字符数量可以上亿、不存在字节序问题且容错性较高,但它也存在以下几点不足:

  • UTF-8 编码方式对英语而言可以最大限度节约存储空间,但对于中日韩等国家的语言而言它则浪费了存储空间。
  • UTF-8 的可变化的字节长度带来了效率上的问题,无论是计算字符数、执行索引操作等效率都不高。为解决这一问题常将其转化为 UTF-16/UTF-32 编码格式后执行相关操作,执行完毕后再将其转换回去,而这降低了信息处理的效率。

综上,我们可以看到,虽然 UTF-8 也存在一些问题,但相比其他二者而言,它突出的优势尤其是不存在字节序以及容错性高的优势,使得它成为了当今网络时代文本信息交换的通用规则。

2.3 音频的存储

与文本不同,音频audio)是不可数的随时间变化的连续实体,我们不可能记录每一个时刻的声音密度,因此在音频的存储中,存在一个重要的概念:采样sampling). 所谓采样即是等间隔地采集一个音频信号在有限个时间点上的密度值,图 2-14 展示了一个音频信号在一秒内的采样情况。

图 2-14 一个音频信号的采样

每秒采集的样本数称为采样率sampling rate),例如上图中音频信号的采样率为 10 个/s,通常而言,40000 个/s 的采样率对音频信号来说就已经足够好了。得到样本后,还需进行量化(quantization)即将样本取值截取为最接近的整数值,这样样本将以无符号表示法或有符号加绝对值表示法的方式存储于计算机中。分配给每个样本的位的数量称之为位深度(bit depth),这样位深度乘以采样率即为一秒钟的音频所需的存储空间,它被称为位率(bit rate)。例如:我们使用 40000 个/s 的采样率以及 16 位/样本 的位深度,则音频的位率为 625 KB/s ,即每秒音频所需的存储空间为 640 KB.

当今音频编码的主流标准是视频压缩方法动态图像专家组MPEG, motion picture experts group)的一个修改版:MPEG 第三代音频压缩格式MP3, MPEG audio layer 3),它采用 44100 个/s 的采样率以及 16 位/s 的位深度,其位率达到约 689.06 KB/s,即每秒音频占用约 689.06 KB 的空间,另外它还会用到去掉人耳无法识别的信息的压缩方法对音频作有损压缩。

2.4 图像的存储

计算机中对图像的存储有两种不同方式:光栅图/位图raster/bitmap graphic)和矢量图vector graphic)。

光栅图将原图像分割成很小的像素pixel / picture element),每个像素存储有图像单元的色彩信息。依据使用的位模式长度的不同,色彩信息的存储又分为真彩色true-color)和索引色/调色板色indexed color / palette color)两种方式。前者使用 24 位,每个三原色(RGB, red, blue, green)占 8 位,因此总共能表示 2 24 = 16777216 2^{24}= 16777216 224=16777216 种颜色,后者通常只使用 8 位,它从真彩色这一大色彩集中选择其中一小部分具有代表性的颜色并对其建立索引,为选中的颜色赋一个 0-255 之间的值。如果我们拍摄一张 300 万像素的照片,当使用真彩色模式时,未压缩的照片大小约为 8.58 M,当使用索引色模式时,其大小则仅为真彩色模式下的 1/3,即 2.86 M. 表 2-15 列出了一些真彩色对应的 RGB 值,图 2-16 则展示了索引色与真彩色的关系。

表 2-15 一些真彩色对应的 RGB 值
图 2-16 索引色与真彩色的关系

目前基于光栅图的图像的实际编码标准有很多,例如常见的联合图像专家组JPEG, joint photographic experts group)、便携式网络图形PNG, portable network graphics)、图形交换格式GIF, graphical interchange format)等。其中 JPEG 是采用真彩色模式的有损压缩图像,PNG 是采用真彩色或索引色的无损压缩图像,而 GIF 是采用索引色模式的无损压缩的多幅图像。可以看到这些常见的图像编码标准都对图像数据作了压缩处理,这大大减小了图像占用的存储空间。关于数据压缩的详细内容,我们将在后续章节中加以讨论。下面我们来看一下计算机存储图像的另一种截然不同的方式:矢量图。

光栅图存在两个明显的缺点:一是文件体积较大、二是放大图像将导致图像变得模糊不清。矢量图则不存在上述两个问题,它将图像分解成线段、矩形、圆形等几何图形的组合。例如对半径为 r r r 的圆形,计算机只需要存储圆的半径、圆心位置、线的类型和颜色、填充的类型和颜色以及它们之间的关系等几点基本信息。当要改变图片大小时,计算机只要依据新的圆的半径及其与其他信息的关系计算出其他信息的值就可以完成新图形的绘制。可以说,矢量图是由定义如何绘制几何图形的一系列命令构成的,因此它也被称为几何模型面向对象图形。但世界的图像是异常丰富的,单靠几个几何图形显然无法还原出一个真实的世界,所以矢量图不适合存储照片,它常用于 Flash 动画制作(flash 是交互式矢量图和 Web 动画标准),一些计算机字体的创建以及计算机辅助设计 (CAD, Computer Aided Design) 等领域。

2.5 视频的存储

视频video)是图像(帧,frame)在时间上累加的结果,因此视频的存储就是将每一幅图像或帧转化为一系列位模式并存储。当然实际当中视频的存储都使用了压缩技术,而这已经超出了本章的范围,我们将在后续关于数据压缩的章节中继续讨论音频、图像、视频的存储问题。滴水穿石,非一日之功,真相离我们还有很远的距离,但可以预见的是,它正迈着坚实的步伐朝我们走来,现在就让我们好好养精蓄锐,他日收拾行囊勇攀高峰,登凌绝顶一览众山,自当不在话下。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值