一、浮点数在内存中的存在形式
任意一个浮点数v可以表示为:(-1)^S*M*2^E;
(-1)^S表示符号位,S为0时表示正数,S为1时表示负数;
M表示有效数字,1<=M<2;
2^E表示指数位。
eg:V=5.5(十进制浮点数)=101.1(二进制浮点数)=1.011*2^2
即:S=0,M=1.011,E=2
针对S、M、E是如何存储在4个字节(32个比特)中:
当E不全为0或1时:
S存符号数0或1;E在原本基础上加127(float型)或加1023(double型),转换为二进制存储;M中只存小数点后面的数,不够位数时0补齐,小数点前一直为1可不存,提取完在左边第一位加1。
当E全为0时:
v是一个接近0的很小的数,真实的E为:1-127或1-1023;有效数字M不再加上第一位的1,而是还原为0.XXXXX..的小数;
当E全为1时:
有效数字M全为1时,表示正负无穷大。
eg: 针对上式中v=5.5时,S=0,M=1.011,E=2
S=0直接存放;单精度浮点数,E=2存放时加上127,E=2+127=129,其二进制为:10000001,即在E中存放的8个数为:10000001; M=1.011,只存放小数点后面的数,不够23位数时0补齐,即在M中存放的23个数为:0110000000000000000000,所以最终以浮点数所存的为:0100000010110000000000000000000。
二、关于浮点数在内存中的存储有关例题
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int n = 9;
float* p = (float*)&n;
printf("%d\n", n);
printf("%f\n", *p);
*p = 9.0f;
printf("%d\n", n);
printf("%f\n", *p);
}
int n=9,整数的内存:00000000 00000000 00000000 00001001
针对第一个输出:变量是以整数存放,以整数取出,输出为9;
针对第二个输出:变量是以整数存放,以浮点数取出;存放的为:00000000 00000000 00000000 00001001 ,浮点数形式取时,按照SEM原则取,S:0;E:00000000; M:000000000000000 00001001。E全为0,真实的E为1-127=-126;浮点数为:(-1)^0*0.000000000000000 00001001*2^(-126),很小的数,精度有限,输出为0;
针对第三个输出:变量是以单精度浮点型存放,以整型取出;9.0(十进制浮点数)=1001.0(二进制浮点数)=1.001*2^3=(-1)^0*1.001*2^3; SEM原则:S为0,E为3+127=130(10000010),M为0010000000000000000000; 以浮点数存放的为:0100000100010000000000000000000; 当以整型取出时,正数的原码等于补码,该数对应的十进制为:1091567616,输出为:1091567616。
针对第四个输出:变量是以以单精度浮点型存放,以单精度浮点型取出,取出时需注意M最左边加1,(-1)^0*2^(2^7+2^1-127)*1.0010000000000000000000=1.001*2^3=1001.0=9.0,输出为9.000000;
结果: