浮点数在内存的存储
1. 前言🚩
2. 浮点数存储与整型存储的关系🚩
如果想直接查看浮点数在内存中的存储比较难,这里我们举一个例子代码来看看
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;
}
但是我们发现中间两个打印很不符合逻辑,一个打印的是0,还有一个打印了很大的数,也可能是打印的随机值,到这里我们可能已经知道了浮点数在内存中的存储规则和整型是完全不一致的,整型的存储补码在内存中,并且分为有符号位整型和无符号位整型,那么浮点数是怎样存储的?
3. 浮点数存储规则🚩
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数 V 可以表示成下面的形式:
这个规则是什么意思呢?我们举个例子,比如这里有一个浮点数为 5.5.我们把这个十进制的浮点数先转换为二进制的浮点数,为 101.1 1.然后二进制的101.1可以写成1.011×22 2.转换为这种形式后,我们就一一对应上面的S,M,E.
- S=0(因为这个数大于0)
- M=1.011
- E=2
划重点! 相当于所有的浮点数都可以用S,M,E这三个数表示出来,所以我们的内存中只需要存储这三个数即可代表浮点数:
然而对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
4. IEEE 754特殊规则🚩
IEEE 754对有效数字M和指数E,还有一些特别规定:
这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。
至于指数E,情况就比较复杂
懂了这些规则,我们前面距离的5.5浮点数在内存中的存储就应该是这样的:
5. 从内存中取出E的情况🚩
指数E从内存中取出还可以再分成三种情况:
- E不全为0或不全为1
- E全为0
- E全为1
6. 对前面代码的解释🚩
我们把前面的代码和截图拿过来:
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;
}
和最后的结果保持了一致,我们的分析是正确的!