关于数据存储的分享~
先声明,本文很多信息都是来源于《计算机科学导论》,起码引子是在那儿,一边学习,一边探索,一边分享。
补充前一章,在位置化数字系统之外,还有非位置化数字系统,这里面比较知名的就是,罗马数字系统。
其中I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000,罗马数字系统中仅有如上6个字符,如果按照上一章中位置化数字系统的理解,肯定是六进制数了。但这里不同。
比如经常见到的 III = 3, IV = 6, VI = 4, 这里面到底是怎么代表具体的量的,其实很简单,所谓非位置化数字系统,那么肯定就是于符号所在的位置没有关系,罗马数字系统中遵循如下的规则:
1)当一个带有较小值得符号位于一个带有同等值或较大值得符号的后面,这些值相加;
2)当一个带又较小值得符号位于一个带有较大值得符号的前面,用大值减去小值;
3)如果S1*10《S2 ,则符号S1不能出现在符号S2之前。例如,I和V不能出现在C前面;
4)对于大数字,在6中符号(出I意外的所有符号)中的任意一个上方加横杠表示乘以1000,例如,-V,我这里电脑没找到表示的方法,只要理解,这个V前面的-,应该是在V头顶上的,那这个新的符号就是代表V*1000,也就是5000,C,D,M什么的也是这样。
5)罗马数字系统中没有0的概念,虽然他们有单词Nulla(空)来表达零的概念。
好了,本来要介绍新的一章知识的,结果写上一章中的非位置化系统写了半天。
这里要写的数据存储,也并没有太过深入。我们都知道信息在计算机中是用二进制存储的,这些信息包括什么呢,这些信息其实就是数据,那又都是什么样子的数据,包括,数字、文本、音频、图像和视频,可以统称为多媒体信息。
然后,我们分别介绍针对这些多媒体信息都是如何转化为二进制数据,又是如何存储的。
基础概念:
计算机中的最小单位是位(bit, binary digit的缩写),它是0或者1。为了表示数据的不同类型,应该使用位模式,它是一个用位组成的序列,有时也称为位流。通常长度为8的位模式称之为1个字节(byte)。
那么如何存储数字?
有两个问题需要解决:
1)如何存储数字中的符号;
2)如何显示十进制中的小数点;
针对小数点的存储,就分为两种,定点和浮点,所谓的定点就是,已经指定好了小数点左边是多少位,右边是多少位,比如一个存储单元是16位,那么我们指定好小数点右边是2位,那么其左边就是14位,但是如果遇到1111···1.0001这种数据,其保存时就会因为精度不够而失真,因为其只能保存小数点后面2位,也就是.00,同样,左边的整数部分也会出现这样的截断问题;而浮点,就免去了这类问题,其就是针对实数设计的,所以考虑了小数的情况。
在存储整数时,有
1)无符号表示法,也就是仅表示非负数,没有单独的一位来表达正负的概念;
2)符号加绝对值表示法,也就是说,在第一个二进制位,用以表达正负,0代表正数,1代表负数;这里会有两种表达0的形式,即+0和-0;
3)二进制补码表示法。这种方法是当前所有计算机都在使用的表示方法。也就是,用原码表示非负数,用补码表示负数。
这里介绍下原码,就是数据转换为二进制码;反码,将原码的各位都反转,即0变成1,1变成0,那么就形成了反码;补码,首先,从右边复制位,直到有1被复制,然后,反转其余的位,还有一种简单的计算方法,先对原码进行一次反码运算然后再加上1得到结果。
在二进制补码表示法中,最左位决定了符号,如果它是0,该整数为正;如果是1,该整数为负。
至于为什么要用补码来表示,而且当前计算机都这么使用。
放几个链接:http://www.douban.com/note/223507364/
http://blog.csdn.net/bendanban/article/details/8681456
简单讲,就是因为芯片设计中,只有加法器,没有减法器,为了考虑硬件设计的成本,将负数设计为补码,这样子,减法操作就变成了 + 补码 的形式,这样子就可以用加法器来代表减法了,简易了ALU的难度。
同样和符号加绝对值表示法一样,二进制补码也是将长度一分为二,一半表示正数,一半表示负数,也就是比如4位二进制,可以表示2^4的长度,也就是16个数字,但是由于一半表示正数,一半表示负数,其能表示的整数范围也就是7~-8,其中0~7是正整数,0~-8是负整数;这也确保了,首位是0时,代表正数,首位是1时,代表负数。
在存储实数时,也就是包括小数位时,有:
定点表示法和浮点表示法,定点表示法前面已经说过了,而浮点表示法如下:
一个数字的浮点表示法由3部分组成:符号、位移量和定点数。其实浮点表示法映射到十进制,那就是科学计数法。
在一个二进制数规范化后,我们只存储了一个数的三部分信息:符号、指数和尾数(小数点右边的位)。如下
+ (符号) 2^8(8就是指数) 1.0001110101(尾数)
上面就是代表了+1000111.0101
这里注意,小数点和定点部分左边的位1并没有存储,它们是隐含的。
但是,尾数可以作为无符号数存储,而指数,是有符号的数,可以是正的幂,也可以是负的幂。尽管尾数,可以用二进制补码表示法来存储,但被一种称为“余码系统”的新的表示法取而代之。在该余码系统中,正的和负的整数都可以作为无符号数存储,为了表示正的或负的整数,一个正整数(称为一个偏移量)加到每个数字中,将它们统一移到非负的一边。这个偏移量的值是2^(m-1) -1,m是内存单元存储指数的大小。
余127码,指数是8位;余1023码,指数是11位。
其实上面的补码和余码,都涉及到模和底的数学问题,详细了解的话,可以看下如下链接文章:
https://www.zhihu.com/question/20159860/answer/21113783
数字的存储介绍完了,那么如何存储文本?
针对文本的存储,那就真的是,一个二进制数代表一个符号,有多少个符号就需要与多少个二进制数对应了。其中,有最开始的128种符号的ASCII码,典型的欧美字母的,一旦涉及到博大的欧洲和亚洲字符,那肯定不够了,于是又了Unicode,当前已经用32位二进制数来表示了,足够了。
具体的可以见如下链接:
http://www.php100.com/html/it/biancheng/2015/0316/8789.html
如何存储音频呢?
音频就和上面不同了,因为文本毕竟还是可数的实体组成(可以统计出有多少个字符,多少个文字等)。但是音频是不可数的,音频是随时间变化的实体,我们只能在每一个时刻度量时间的密度。当我们讨论用计算机存储声音时,我们的意思是存储一个音频信号的密度。
音频是模拟数据的例子。由模拟数据到数字数据,需要经过采样(在模拟信号上选择数量有限的点来度量它们的值记录下来,音频中就是每秒采集有限数量的点来记录各点的密度),量化(将样本的值截取位最接近的整数值得一种过程),编码(量化的样本值需要被编码成位模式)。
对于每个样本系统需要分配多少位,其数量被有时被称为位深度;那么,位深度为B,样本数为S的音频存储就是S*B位,该乘积有时称为位率R。
如何存储图像呢?
存储在计算机中的图像使用两种不同的技术:光栅图或矢量图。
光栅图(位图)类似于音频,不同的是,音频是随时间变化的数据密度,而图像是随空间变化的数据密度(色彩)。
这种情况下的采样通常被称为扫描,样本称为像素(代表图像元素)。这里的样本,有时候被称为解析度,即每英寸的方块或线条需要记录多少像素。而位深度,就是色彩深度,也就是用于表现像素的位的数量,有两种,一种是真彩色(24位,RGB三原色各8位),另一种是索引色(256种)。JEPG用的真彩色,GIF用的索引色。
矢量图图像编码方法并不存储每个像素的位模式,一个图像被分解为几何图形的组合,例如,线段、矩形或圆形等,每个几何图形都是有数学公式表达的。也就是说,矢量图是由定义如何绘制这些形状的一系列命令构成的。
因此,光栅图有两个缺点,即文件体积太大和重新调整图像大小有麻烦,而矢量图其实只是公式,在重塑或者调整大小时很方便,不会变得粗糙;光栅图放大时,肯定是会粗糙的。但是矢量图不适合存储照片图像的细微精妙,毕竟公式都是有规则的,很多随机精妙的东西不能表达,矢量图往往用于绘图软件中的,或者Flash中用的等。
如何存储视频呢?
视频是图像(称为帧)在时间上的表示。也就是说,视频是随空间(单个图像)和时间(一系列图像)变化的信息表现。通过上述的图像存储和音频存储,就知道如何用一系列位模式来存储视频了。