浮点型在内存中的存储
常见的浮点数:
3.14159 1E10
浮点数包括:float、double、long double类型
浮点数表示的范围:float.h中定义
int main() {
int n = 9;
float* pfloat = (float*)&n;
printf("n的值:%d\n", n);
printf("*pfloat的值:%f\n", *pfloat);
*pfloat = 9.0;
printf("n的值:%d\n", n);
printf("*pfloat的值:%f\n", *pfloat);
return 0;
}
n占4 byte,以整型的形式放9,小端09 00 00 00
*pfloat以浮点数的视角存储9.0,说明浮点数和整数在内存中存储的方式有区别
IEEE 754标准
浮点数V可以表示为:(-1)^S * M * 2^E
(-1)^S 表示符号位。S=0时,V为正数;S=1时,V为负数。
M 表示有效数字。1≤M<2
2^E 表示指数位
例如:
浮点数:5.5
写成二进制:101.1即1.011*2^2
S=0,M=1.011,E=2
有了S、M、E,也可以还原出原浮点数
单精度浮点数存储模型
float:
双精度浮点数存储模型
double:
IEEE 754规定,在计算机内部保存 M 时,默认这个数的第一位总是1,因此可被舍去,只保存后面的部分。比如保存1.01的时候,只保存01,读取时再把第一位的1加上去,这样可以节省1位有效数字。
而 E 作为一个无符号整数,如果 E 为8位,取值范围为0~255;如果 E 为11位,取值范围位0~2047。但是,科学计数法中 E 是可能为负的,所以IEEE 754规定,存入内存时 E 的真实值必须再加上一个中间数,对于8位的 E,中间数是127;对于11位的 E,中间数是1023。比如2^10的 E 是10,保存成32位浮点数时,必须保存成10+127=137,即10001001。
浮点型从内存中取出
E不为全0或不为全1
指数 E 的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。比如:0.5的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位0000000 00000000 00000000,其二进制表示形式为0 01111110 00000000000000000000000
E全为0
这时,浮点数的指数 E 等于1-127 (或1-1023) 即为真实值,有效数字M不再加上第一位的1,而是还原为0.××的小数,这样可以表示±0,以及接近0的很小的数字。
E全为1
如果有效数字 M 全为0,表示±∞
//前例解释
printf("n的值:%d\n", n);
//00000000 00000000 00000000 00001001——9的二进制
printf("*pfloat的值:%f\n", *pfloat);//以浮点数的视角存储9.0
//0——S
//00000000——E
//0000000 00000000 00001001——M
//E为全0,M补0成0.0000000 00000000 00001001
//读出为0.0000000 00000000 00001001*2^(-126)
*pfloat = 9.0;
printf("n的值:%d\n", n);
//1001.0——二进制
//1.001*2^3——科学计数法
//0 10000010 00100000000000000000000
//1091567616——十进制
printf("*pfloat的值:%f\n", *pfloat);//浮点数存浮点数取