当前位置:网站首页>数据的存储(下)——浮点型在内存中的存储
数据的存储(下)——浮点型在内存中的存储
2022-08-11 01:36:00 【~小明学编程】
作者:~小明学编程
文章专栏:C语言基础知识
目之所及皆为回忆,心之所想皆为过往
目录
我们现在已经了解了整数在内存中的存储接下来我们来一起了解一下,浮点数是如何在内存中存储的。
问题引入
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;
}我们先来看一个例子,上面的代码的输出结果是什么

9和9.000000的结果在我们的意料之中,但是剩下的两个结果就不是我们所能理解的了。
想要知道剩下两个为啥会这样我们首先要了解一下浮点数在我们的内存中是如何存储的。
浮点型在内存中的存储
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位
十进制的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。
IEEE 754规定:
对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
M
IEEE 754对有效数字M和指数E,还有一些特别规定。
前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。
IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。
以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。至于指数E,情况就比较复杂。首先,E为一个无符号整数(unsigned int)这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中出
现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
然后,指数E从内存中取出还可以再分成三种情况
E的情况
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将
有效数字M前加上第一位的1。
比如:
0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为
1.0*2^(-1),其阶码为-1+127=126,表示为
01111110
而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进
制表示形式为: 00 01111110 00000000000000000000000
E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,
有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于
0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);
解决问题
既然我们了解了浮点数的存储那么接下来我们就对问题进行分析
9的二进制表示为
0000 0000 0000 0000 0000 0000 0000 1001当我们以浮点数的形式打印时S=0,M=000 0000 0000 0000 0000 1001,E=00000000
我们知道当E全为0且S=0,就表示无穷小也就是打印0.0000000的原因。
接着我们将整数n通过指针的方式赋值成9.0。
S=0,9.0转换成二进制位1001.0->1.001*2^3,M=1.001,E=3+127=130
S=0,M=001 0000 0000 0000 0000 0000,,E=10000010
即 0 10000010 001 0000 0000 0000 0000 0000
我们以整型的方式直接读取就会是一个很大的数字1091567616
边栏推荐
- [GXYCTF2019]BabySQli
- Ambari Migrates Spark2 to Other Machines (Graphic and Text Tutorial)
- HCIP-R&S By Wakin自用笔记(3)OSPF之引入外部路由、Forwarding-Address、汇总、特殊区域
- paddle2.3和torch1.8在SentenceBert上的性能对比
- The latest domestic power supply manufacturers and pin-to-pin replacement manuals for specific models are released
- J9 Digital Theory: DAO governance is more like an ecological process: governance is native to the network and continues to evolve
- 数据分析面试手册《统计篇》
- 16. Sum of the nearest three numbers
- How to determine the size of the version number
- MySQL索引与事务
猜你喜欢

This Thursday evening at 19:00, Lesson 5 of the sixth phase of knowledge empowerment丨OpenHarmony WiFi subsystem

nvidia-smi详解

最新国产电源厂家及具体型号pin-to-pin替代手册发布

连流量染色都没有,你说要搞微服务?

微服务概念

Flink二阶段提交

第二课第一周第4-6节 医学预后案例欣赏+作业解析

MySQL advanced query

Update chromedriver driver programming skills │ selenium

【服务器数据恢复】raid5崩溃导致lvm信息和VXFS文件系统损坏的数据恢复案例
随机推荐
单面PCB布线阻抗的工程设计
R language multiple linear regression, ARIMA analysis of the impact of different candidates in the United States on the economic GDP time series
【websocket】
《QA离业务代码能有多近?》轻量级单元测试方案
Elastic scaling of construction resources
vim simple save window id
联盛德W801系列6-从微信小程序的角度来分析W801的蓝牙通信源码(indicate方式)
进程间通信方式(2)有名管道
【websocket】
软件测试面试题:什么是Negative测试?
【微波工程学习记录1】功率分配器和定向耦合器
Ora - 00001 in violation of the only constraint
OpenWrt之opkg详解
The iterator and generator
数据分析面试手册《统计篇》
阿里的数据同步神器——Canal
MySQL advanced query
url转成obj或者obj转成url的方法
22/8/9 Collection of Greedy Problems
Detailed explanation of the opkg of OpenWrt
