整型的数据在内存中以补码的形式进行存储,而浮点数却不是.一般情况下,在32bit和64bit操作系统下,float使用四个字节存储,double使用八个字节存储,但是浮点数的存储都遵从IEEE规范,使用原码进行存储.
存储原理
在浮点数的存储中,将浮点数分为三个部分进行存储:
- 符号位(Sign):存储符号位,0表示正,1表示负.无论使用多少bit存储浮点数,符号位只占用1bit;
- 指数位(Exponent):存储采用二进制科学计数法表示浮点数的指数部分.使用32bit存储时,指数位占用8bit;使用64位存储时,指数位使用11位;
- 位数部分:存储采用二进制科学技术法表示浮点数的位数部分.使用32bit存储时,尾数占用23位;使用64位存储时,尾数占用52位.
在浮点数的存储过程中,首先需要将浮点数转化为科学计数法数据,然后对各个部分进行存储.
符号位
浮点数为正数,则存储0;浮点数为负,则存储1.
指数位
由于指数部分有正有负,这时候就会出现(假设使用8位二进制表示)
- +0: 00000000
- -0:100000000
但事实上0只有一个,这种表示会浪费一个空间,而且会导致混淆.所以浮点数的指数部分采用了一个特殊的方式来进行指数位存储.在使用n位二进制进行指数位存储时,取真实的指数位位re,存储的指数位为se,则存在如下转化关系:
se = re + 2^(n-1) - 1;
即通过将真实的指数位进行偏移之后存储,所以指数位可以存储在区间[-(2^(n-1)-1), 2^n]之间的数据,大于这个区间则数据会溢出.所以使用32bit进行存储时,n=8,指数位真实值需要+127得到真实的指数位存储值;使用64位进行存储时,n=11,指数位真实值+1023的到指数位的存储值.
尾数部分
在这个处理中,由于整数部分一直为1,所以可以不存储整数部分的1,只存储小数部分数据即可.
存储实现
根据上边的原则,模拟一下实际的存储过程
//定义一个float变量
float a = 8.25;
按照存储原则:
8.25=1000.01=1.00001 * 2^3
符号位:浮点数为正,存储0
指数位:re=3,se=3+2^7-1=0b11+0b01111111 = 0b10000010
尾数位:1.00001,所以只需要存储0b000 1000 0000 0000 0000 0000
所以8.25在计算机中的存储为:
0100 0001 0000 1000 0000 0000 0000 0000
//定义一个double变量
double b = 175.0;
按照存储原则:
175=0b00000000000000000000000010101111 = 1.0101111 * 2^7
符号位:负点数为正,存储0;
指数位:re=7, se=7+2^10-1=0b10000000110
尾数位:0b0101111
所以double b=175在计算机中的存储为:
0100 0000 0110 0101 1110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000