深度剖析数据在内存中的存储2——浮点数数在内存中的存储

根据国际标准IEEE:任意一个二进制浮点数V能够表示为下面形式:
(-1)^SM2^E:
(-1)^S表示符号位,当S为0,V为正数;当S为1,V为负数。由其物理结构决定了,浮点数为有符号数。
M为有效数字,大于等于1,小于2。
2^E表示指数位。
eg:5=>0101=>(-1)^01.012^2. S=0,M=1.01,E=2
规定:对于32位的浮点数(单精度浮点数存储),最高1位是符号位(S),接着的8位为指数位(E),剩下的23位是有效数字位(M),不满23位后面补0。
对于64位的浮点数(双精度浮点数存储),最高1位是符号位(S),接着的11位为指数位(E),剩下的52位是有效数字位(M)。
对于有效数字M和指数E会有一些特殊规定:
一、由于1<=M<2,因此小数点前一定是1,因此能够省略1和小数点,这样一来,对于单精度浮点数存储方式,23位有效数位存的都是小数部份数。读取时,小数点和1都会被自动加上。等于能够保留24位有效数字。双精度同理。
二、对于指数E来讲,首先说明他是一个无符号整数,对于单精度浮点数存储方式,E共占8位,则E的取值范围为0~255。可是科学记数法中,指数是能够为负数的,因此规定,存入内存时,E的真实值必须加上一个中间数,对于8位的E,这个中间数为(255/2=)127(实际表达范围-127~128),对于11位的E,这个中间数为1023(实际表达范围-1023~1024)。取数时,再减去127/1023即为实际值。(移码)
eg. 由上面可知,5的指数为2,对于单精度浮点数存储方式,实际在内存中存储的数为127+2=129=>1000 0001。
注意:由于当E为全零时,实际上指数为-127,表示一个接近零很小的数,所以浮点数不能与零比较,用精度来代替。当E为全一时,表示的±无穷大。
综述:整数与浮点数的存储方式彻底不一样,整数存取为原反补码,浮点数为S、E、M
练习代码:ide

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

int main()
{
    int n = 9;                        //0000 0000 0000 0000 0000 0000 0000 1001
    float pFloat = (float)n;          //将9取出,转为浮点型,再存给pFloat
    float *pfloat = (float *)&n;      //将n的地址转为浮点数地址(即看待n的方式变为浮点数)。
    printf("n=%d\n", n);
    printf("pFloat=%f\n", pFloat);
    printf("*float=%f\n", *pfloat);   //解引用后以浮点数形式看待空间里的值  0 00000000 00000000000000000001001   S=0,E=0,(-127)
    *pfloat = 9.0;                    //1001 实际n空间中存的值0 00000011 00100000000000000001001 
    printf("n=%d\n", n);              //转换为整数为 1091567616
    printf("*float=%f\n", *pfloat);   // 9.000000
    system("pause");
    return 0;
}