整数在浮点数中的存储
介绍浮点数的存储之前,先来谈整数在计算机内存中的存储。我们知道计算机是二进制计数方法,我们仅用0和1来计数,反映在物理层面就是电路的通与不通。我们还知道,计算机中把整数分为signed int(有符号整数)和unsigned int(无符号整数)。简述一下区别:
首先引入三个概念:原码,补码,反码
原码:将数字直接用二进制表示出来的就是原码:举个例子15=2^3+2^2+2^1+2^1;所以二进制就是
00000000 00000000 00000000 00001111;这就是正数15的原码,也是它的反码和补码;是的,正数的原码反码和补码相同
反码:原码的符号位不变,其他位按位取反得到反码。举个例子:-15。在存储整形的32个比特位中,最高位是符号位,1表示负,0表示正。所以-15的原码是
10000000 00000000 00000000 00001111;
反码是11111111 11111111 11111111 11110000;
补码:反码加一:
补码 11111111 11111111 11111111 11110001
所以数据在计算机中存储的其实是补码(原码符号位不变,其他位按位取反,再加一)。
OK,下面介绍浮点数的存储:先看定义
所以说,我们只需要存储S,E,M这三个数就可以了
S:0和1两种情况,所以只需要一个bit就可以存放;
M:float类型需要8个bit位,double类型需要11个比特位。另外我们知道在科学技术法中,M是大于一且小于二的,所以存储过程中我们可以存储M小数点后面的数字,这就节省了一个bit的空间。使得23(52)位的空间可以保存24(53)个数字。节省了空间。
E:首先声明这里的E是无符号整数,但实际应用中,科学计数法的指数部分是有可能为0的;所以C语言中规定实际存储在E中的值要在原来的基础上加上一个中间值;32位浮点数这个数是2^7-1=127;64位中这个数是2^10-1=1023;这样就在一部分程度上避免了负数无法存储的问题。
另外,我们思考两种极端情况:
1、当E很小时,即使存储过程中加上一个中间数也仍然有可能为0;这时我们可以想象到这是一个非常小的浮点数,所以我们在读取M的时候也不再需要加上1,而是保留0.xxxxxxx的形式,表示一个非常小的数。
2、当E很大时,存储到E的内存块中为全1的情况,这时就表示正负无穷大的数字。
以上就是我对浮点数存储的简单理解,如果哪里有误,还请大家不吝赐教,谢谢!