当前位置:网站首页>【C语言进阶】——剖析入微数据在内存中的存储 【下】(浮点数存储)
【C语言进阶】——剖析入微数据在内存中的存储 【下】(浮点数存储)
2022-07-28 16:31:00 【发疯的橙子】
浮点数在内存中的存储
3.1一个栗子
浮点数在内存中怎么存储的呢?我们可以在float.h头文件下查看数据范围。
浮点数存储的例子
#include<stdio.h>
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//9
printf("*pFloat的值为:%f\n", *pFloat);//0.000000
*pFloat = 9.0;
printf("num的值为:%d\n", n);//1091567616
printf("*pFloat的值为:%f\n", *pFloat);//9.000000
return 0;
}
输出结果和我们想的大不相同,这是为什么呢?让我们来一探究竟
3.2浮点数存储规则
num和*pFloat在内存中明明是用一个数,为什么浮点数和整数的解读结果会差这么大?
要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。
详细解读:
根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数 V 可以表示成下面的形式
- (-1)S * M * 2E
- (-1)S 表示符号位,当S=0,V为正数; 当S=1,V为负数。
-M表示有效数字,大于等于1,小于2.
-2E表示的指数位。
再举个栗子
十进制的5.5,写成二进制是101.1,相当于1.01 * 22。(101.1,小数点后的1,其实是2-1等于0.5)
那么,按照上面V的方程式,可以得出S=0,M=1.01,E=2。
IEEE 754 规定:对于32位的浮点数,最高的1位是符号位S,紧接着的8位是指数E,剩下的23位为有效数字M。

对于位的浮点数,最高1位是符号位S,紧接着的11位是指数E,剩下的52位为有效数字M。

可是,对于有效数字M和指数E,到底是怎么存储的呢?IEEE 754还有一些特别的规定:
前面说过,1<=M<2,也就是说,M肯定是1.xxx的形式,其中xxx表示小数部分。在计算机内部保存M时,既然M肯定是1.xxx的形式,所以默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxx小数部分。比如保存1.01时,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字,以32位浮点数为例,留给M只有23位,将第一位的1舍去后,等于可以保存24位有效数字,精度也就提高了。
至于指数E,情况就比较复杂:
首先,E作为一个无符号整数(unsigned int)这就意味着,如果E为8位,它 的 取 值 范 围为0~ 255;如果E为11位,取值范围为0~ 2047。但是,我们知道,科学计数法中的E是可能出现负数情况的。
根据科学计数法E可能出现负数,所以 IEEE 754 规定,存入内存时E的真实值必须再加上一个真实数 ,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如:2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
再再举个栗子(E为负数情况)
例子:5.5(正数)
例子:5.5
int main()
{
float a = 5.5f;
//101.1——>1.011*2^2
//S=0,M=1.011,E=2
//真实存储的是 S=0,M=011,E=2+127
//假设现在是内存区域:
//0 10000001 01100000000000000000000
//转换十六进制:4个二进制为一个16进制
//40 b0 00 00
return 0;
}

说明:浮点数在内存中存储也存在大小端!讲到现在就清楚了浮点数是如何在内存中存储的。当然你感兴趣的话,可以私下去测下double~
前面讲的是如何存进去的方法,接下来是,指数E从内存中取出还可以再分成3种情况:
E不全为0或者不全为1

E为全1
这时,浮点数的指数E等于1减去127或者(1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
//当E加了127或者1023再放入内存,
//结果存的全是0,说明真实的E非常小
//
//比如:
E= -127
-127+127=0//存入内存的值
** E为全1**
这时,如果有效数字M全为0,表示示±无穷大(正负取决于符号位s);
好啦,浮点数规则就说到这里了~
解释前面的题目:
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//9
printf("*pFloat的值为:%f\n", *pFloat);//0.000000
*pFloat = 9.0;
printf("num的值为:%d\n", n);//1091567616
printf("*pFloat的值为:%f\n", *pFloat);//9.000000
return 0;
}
下面,让我们回到一开是问题:为什么0x00000009还原成浮点数,就成了0.000000 ?
好啦,朋友萌,浮点数存储到这就讲完啦~如果没明白怎么肥事,建议多看几遍喔 ~
如果你觉得文章不错,记得点赞+分享喔~如果有地方不对,欢迎随时评论指出 ~
边栏推荐
- 软件测试工作内容太简单怎么办?
- 简单易用的APP专项测试工具iTest4.7.0发布啦
- Master JVM interview topics and answers offer get soft (with learning roadmap)
- FreeRTOS learning notes
- [impala] [error reporting solution] impala cannot read or execute the parent directory of dfs.domain.socket.path
- 谈谈“发布后问题”的度量
- Database optimization -- deeply understand the underlying data structure and algorithm of MySQL index
- Visual Object Class介绍PASCAL VOC数据集
- 在PDF中插入文本水印
- Embedded development learning path
猜你喜欢

Redis源码剖析,狠狠地拿捏了,赶紧码住

Talk about the measurement of "post release problems"

2021 年全国大学生数据统计与分析竞赛
![[kibana] problem sorting kibana 7.x no indices match pattern](/img/36/0f85dbe7eea49db8f845a4a4f302cf.png)
[kibana] problem sorting kibana 7.x no indices match pattern "APM-*“

In depth sharing of Ali (ant financial) technical interview process, with preliminary preparation and learning direction
![[atlas] atlas compilation error sorting (all)](/img/bb/2ca51dffc7a09b378be4e581280246.png)
[atlas] atlas compilation error sorting (all)

R中因子(factor)

生信人的20个R语言习题

Jdwp unauthorized rapid utilization

Ant financial mobile testing tool solopi monitoring part of the source code guide.. Continuous update
随机推荐
一篇带你走近Kubernetes概貌与原理
培训软件测试能不能就业
JDWP未授权快速利用
clang format
Encrypt the video and upload it to OSS to achieve high concurrent access
FreeRTOS learning notes
软件测试需求人才越来越多,走上测试道路的人却越来越少?
软件测试到底有没有前景和出路?
Editor MAVON editor for offline use
Talk about the measurement of "post release problems"
mysql实现按照自定义(指定顺序)排序
JVM性能调优
MySQL triggers
零基础转行软件测试到底能不能行?
小白如何零基础学习软件测试?
C # basic interview questions (with answers)
特殊质数js实现
深度分享阿里(蚂蚁金服)技术面试流程,附前期准备,学习方向
Can you read the story?
漫谈测试平台—建设模式探讨