浮点数在内存中的存储

1.浮点数家族包括 float,double,long double 浮点数表示的范围:float.h中定义
整形家族的取值范围可以从limits.h中查看
2.根据IEEE754,任意一个二进制浮点数V可以表示为下列形式
(-1)^ SM2^E
(-1)^S表示符号位,当S=0时,V为正数,当S=-1时,V为负数
2^E表示指数位
M表示有效数字,M>=1且M<2
以十进制数字5.5为例,其转化为二进制为 101.1(小数点后每一位的权重分别为2的-1次方,2的-2次方,2的-3次方,诸如此类)
将其转化为科学计数法(左移2位)即为 1.01*2^2,S=0,E为指数即为2
对于有效数字IEE754规定,因为M是大于一的数,所以在计算机保存M的时候,默认这个数的第一位总数1,因此可以被舍去,只保留后面的部分,1.01只会保留01,等到读取的时候,再把第一位的1加上,这样做的目的可以节省1位有效数字
对于32位的浮点数,IEEE754规定
最高的一位为符号位S,接着8位为指数位E,剩下的23位为有效数字M

浮点数在内存中的存储_第1张图片
而对于64位浮点数,最高的1位是符号位S,接着11位为指数E,剩下52位为有效数字M
浮点数在内存中的存储_第2张图片
对于指数E,首先,E是一个无符号数,故有可能科学计数法给E的是一个负数,为了避免E出现负数,故需要对E进行修正,存入内存E的真实值必须再加上一个数字,如果E为8位,这个中间数为127,如果E为11位,这个中间数为1023
比如,2^10的E为10,存入时需要对E进行修正,加上127为137,137=128+9
故8位E位 1000 1001
然后,E从内存中取出也可以分为三种情况
①当E不全为1或不全为0时,因为存入时对指数E的值进行了修正,使得E加上了127,所以E需要减去127(或1023)得到真实值,再将有效数字M加上第一位的
②当E全为0时,此时E等于1-127(或者1-1023)即为真实值
有效数字不再加上第一位的1,而是还原为0.XXXXX的小数,这样做是为了表示±0,以及接近于0的很小的数字
③.当E全为1时,如果有效数字全为0,表示正负无穷大(正负取决于符号位)

int n=9;
float*pfloat=&n;
printf("%d",n);
printf("%f",*pfloat);
*pfolat=9.0;
printf("%d",n);
printf("%f",*pfloat);

9在内存中以补码存储,即为0000 0000 0000 0000 0000 0000 0001 0001
当以%f去解读时,第一位0表示符号位,代表为正数,而之后的八位0000 0000代表了指数,全0,不再还原有效数字中的1,而是直接以0.XXXXX…的形式,说明了V是一个很小的数,而%f为小数点后六位,所以打印出来的结果为0.000000
而当9.0以浮点型类型存储时,9.0十进制转化为二进制 1001.0,科学计数法为1.0001*2^3符号位S为0,指数位E为3,修正后为127+3=130=128+2有效数字0001,内存中的形式为 0 1000 0010 00010000000000000000000
按照%d形式来读取的结果即为1091567616

float尾数部分为23位,double的尾数部分为52位,由于同时都带有一个固定隐含位(由于存入有效数字到M时小数点前的1将不会存入,取出的时候会加上1),所以float有24个有效二进制位,double有53个有效二进制位,所以他们的精度在十进制中分别是log10(224)约等于7.22位和log10(253)位约等于15.95,因此float的有效数字为7-8位,double的有效数字为15-16位,这些位置包含整数部分和小数部分

你可能感兴趣的:(c语言)