write in front
大家好,我是gugugu。希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
本文由 gugugu 原创 CSDN首发 如需转载还请通知⚠
个人主页:gugugu—精品博客
欢迎各位→点赞 + 收藏⭐️ + 留言
系列专栏:gugugu的精品博客
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本
整数在内存中以二进制补码的形式存储,这个相信大家都很熟悉,那么浮点数又是怎么在内存中存储的呢?这篇博客将给大家详细讲解。
#include
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.000000
又为什么会输出1091567616这么大的数字呢?
在学习玩本章博客之后,就能够明白这道题目。
根据国际标准IEEE(电气和电子工程协会) 754,任意⼀个⼆进制浮点数V可以表示成下面的形式:
V = (−1) S * M * 2E
• (−1)S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
• M 表示有效数字,M是大于等于1,小于2的
• 2E 表示指数位
没关系,博主先举几个例子
首先先说5.5
5.5 = 101.101?
至此 5.5 = (-1)0 * 1.011 * 22
所有的浮点数都可以这么写,各位小伙伴可以自己举几个例子试试吧,当然,别太复杂,否则自己会写吐的。
IEEE754标准还规定
对于32位的浮点数(float),最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
如下图
对于64位的浮点数(double),最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M
如下图
因为-1的0次方等于1,即正数,-1的1次方等于-1,即负数
所以S中只用存储0或者1就可以完成符号的区分。
因为M大于等于1,小于2,所以M都是一点几,
既然都相同,那就可以不用去存储了,直接去存储小数点后面的数字就可以了。
这样做有什么好处呢???
很显然,这样子做就可以省下储存1的那个比特,可以多储存一个二进制位。
从而提高了浮点数的精度。
首先规定了E为无符号整形。
因为可能出现负指数,所以IEEE754标准中提到一个词——中间数,
指数加上这个中间数,就变成了非负整数。
所以,前面提到的5.5,在内存中存储的就是
S=0, E=2+127=129=10000001,M=011,因为未占满,所以后面全部补0,所以
M=01100000000000000000000
浮点数读取有三种情况
当E中既有0又有1时,这是,就是正常情况,根据存储的过程反向操作就行。
当E中全部都是0的时候,
E的真实值会分成非常小,这个时候,这个浮点数也就是会非常非常小,非常接近于0。
编译器就会将E=1-127或者1-1023,注意是1减,而不是0减。
然后M不会在小数点前面重新加上1.了,而是直接变成0.xxxxxx
通过这些操作来表示0或者一个十分接近0的浮点数。
当E中全部都是1的时候,
这时,即使M中的数字为0时,也表示正无穷或者负无穷,即一个超级大或者超级小的数字。
好啦,到这里,浮点数的存储规则讲解的差不多了,现在,我们可以来分析在最开始提出的那个题目了。
#include
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;
}
所以四个答案都得到了很好的解释。
okok,今天第二更奉上,关于浮点数的存储是C语言里面的一处比较重要的底层理解,希望大家能够学到不少东西吧。
!!!!!!!!!!!!!!!!!求关注!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!蹲个一键三连!!!!!!!!!!!!!!!