相信大家对与整数在内存中的存储都不陌生,整数在内存中是以二进制补码的方式进行存储的,那补码与源码的转换这节博客不做讲解,有兴趣的小伙伴可以上网查一下,比较简单。
浮点数与整数的存储方式是否相同?
我们用一个代码来看一下
#include <stdio.h>
int main()
{
int n = 9;
float *pFloat = (float *)&n;
printf("n的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
return 0;
}
大家可以在自己的编译器上运行一下看看结果是什么。
在我的编译器上结果如下
我们不难发现以不同的格式进行打印时就会发现有不同的结果,这其实也就证明了整型与浮点型的数据在内存中的存储方式是不相同的,
浮点数如何在内存中存储
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
V = (−1)S ∗M ∗ 2E
• (−1)S 表示符号位,当S=0,V为正数;当S=1,V为负数
• M 表示有效数字,M是大于等于1,小于2的
• 2E 表示指数位
举例来说:
十进制的5.0,写成二进制是101.0 ,相当于1.01×2^2 。
那么,按照上面V的格式,可以得出S=0,M=1.01,E=2。
十进制的-5.0,写成二进制是-101.0 ,相当于-1.01×2^2 。那么,S=1,M=1.01,E=2。
就比如这个图s用来存储1或者0,这表示这个数据是正数或者负数。
E的存储就有所不同,在浮点数的存储中,E是一个无符号的整型,所以E是不存负数的,但是在我们实际的应用中,E是可以以负数的形式存在的比如0.5。所以在存储E时我们会加一个中间数,float类型的数据加上127,double类型的数据加上1023,再将加后面的数存储到内存中。
而M的存储也不是直接把M的值存储到内存当中,我们可以发现,任何的数据在准话为浮点数的科学技术法时,都可以写为1.xxxxxx型,那么在存储时为了节省空间便不在把1存储到数据当中,而是将1去掉,只存后面的数据,如果说数据不够23位,就应该在数据的后面补0.
浮点数数据的拿取
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。
这样就可以把数据从内存中拿取出来了。
现在你理解浮点数如何在内存中存储了吗,如果理解了,试着分析一下最上面的题吧。