今天,我知道了计算机中数据的存储方式,虽然暂时还是关于数字的存储方式。
众所周知,计算机按照大类可分为数据,硬件和软件,这是基于冯诺依曼模型下现代计算机的组成。我也是按照这个顺序学习的。数据按照单类可分为五类:数字,文字,图像,音频和视频(这里的视频是指动起来的画面,不含音乐和音效的那种),现在大多都是这五类的排列组合而不是只单独的一类(当然,这里说的是大多,而不是全部),这五种排列与组合也有一个学名——多媒体。
从易到难,数字。提到数字,当然第一个想到的就是复数,也就是实数集与虚数集的合集。我们都知道复数的公式是a+bi(其中a与b是实数),也就是说,在计算机中我们可以用两个实数和一个常量i来表示虚数。那么我们只需要研究如何表示一个实数就可以了。可问题来了,一个实数的整数部分,小数部分,小数点和正负号该如何表示呢?可能我们会认为,将位分为四部分,分别代表正负号,整数,小数点和小数,可这样会产生以下问题。
第一个问题就是可表示数字的位数较少。假设正负号占一位,小数点占一位,那么可表示的数字位就少了两个,相对应的,可以表示的数字最多比占满少了四倍,这不是一个小数目。
第二个就是过于复杂。如果我们想要存储一个数字,就必须确定其正负,小数点应该在第几位,后续如果要变化其大小,就必须每次都移动小数点的位置。假设一下,我要定义一组数据,然后每一次改变都需要这样操作,实在是太麻烦了。
所以不能将实数进行一个统一的定义,得按照需求进行分类并分别定义。从需求和历史发展角度来看,我们可分为有小数部分和无小数部分,他们分别称为整数(其实我感觉应该叫定点数)和浮点数。他们名字是根据小数点是否浮动来定义的,因为整数的小数点是固定的,总是在数字的最右边,所以成为定点数或者整数。而有小数部分就需要考虑其精度,所以其小数点的位置是浮动的也就是浮点数。
我们一个一个来,整数又可以按照是否需要正负号分成两类。一个类是不需要正负号,称为无符号整数。在整数中,小数点是默认在位的最右边但是不占位。所以在无符号整数中,所有的位数都被用来表示大小。上一篇文章中提到,计算机中数据是以二进制存储的,也就是说,数字要首先转化成二进制数,然后补全位数使其适应计算机位数,最后放入一开始规划好的内存里。但我们需要注意的是,固定位数的内存所能存储的数字的大小是有上限的,假设位数是N(N是正整数),那么最大可存储的数字是(2^N-1)。如果我们要存储比其大的数字的时候,需要更大的位数。可如果我们在运算时数字超过位数最大值会发生什么呢?答案是溢出。溢出的位数不会存储在内存中,之后会丢失。计算机中只会从右到左存储相应位数的值。
第二类是需要正负号。这里有两种思路来存储,其中一种是绝对值存储。就是用最左边的位存储正负号(0表示正,1表示负),剩下的位全部用来表示数字的大小,用这种存储方式表示的最大正数是无符号整数的一半。需要注意的是,这种方式会产生两个零,以四位为例就是0000和1000。其余存储方式和无符号整数的存储方式相同。同理,这种方式也会有一个存储最大值,也会出现溢出的问题,从负数到正数称为负溢出,与之相反的过程称为正溢出。或许你没有发现,这种方式在运算时会产生很大问题。在进行四则运算时,用的是所代表的绝对值进行运算,也就会闹出 (-5)*(-5)=(-25)的笑话。所以会有下面的新的存储方式。
另外一种就是补码表示法,就是总体思想是一样的,但是原理不同。在介绍之前我们需要知道什么是反码和补码。反码顾名思义就是反过来,1100的反码就是0011。补码有两种算法,其中一种是从右到左复制位上的数字,直到复制第一个1时,随后的所有位都取反码,另外一种就是先取反码然后加1,例如1100的补码就是0100。书上说补码的存在是为了方便运算,具体真假等看到下一章节再说吧。然后之后的转换过程我们就可以看懂了。最左边位表示符号,0为正,1为负,这个前提要知道。第一步,要将数字转化为二进制数,如位数不足,便补全0。然后确定该数是正数还是负数,整数就直接存储在计算机中,如果是负数便按照其补码形式存储在计算机中。要输出数据时,我们需要按照相反的顺序还原该数。如果最左边的位数是0,便直接转化为十进制,这便是输出要数字;如果是1,那么需要先按照求其补码,之后再将补码的结果进行转化成十进制。
补码表示法是将整个范围分为非负数和负数,这样就避免了两个零的存在。
浮点数等明天再说吧,今天还是玩的太疯了,只看了这一点,一定改。