C语言---浮点数在内存中的存储

前面跟大家介绍了整数在内存中的存储,这次再向大家介绍下浮点数在内存中的存储。

我们常见的浮点数有3.14,1E10 等等,浮点数家族包括float,double,long double类型。

浮点数的表示范围在头文件 float.h 定义。

1.浮点数的储存

首先,我们要清楚浮点数于整数在内存中的存储方式是完全不一样的。

浮点数在内存的存储方式有一个国际标准。

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V都可以表示成以下形式:

V  =  (-1)^{S}*M*2^{E}
1.  (-1)^{S} 表示符号位,当S=0时,V为正数,当S=1时,V为负数。
2. M 表示有效数字,M是大于等于1,小于2的。
3. 2^{E} 表示指数位。
举个例子
十进制的 5.5 ,写成二进制位 101.1,相当于 1.01*2^2。
那么按照上面的公式,得到
S=0,M=1.01,E=2。
再举个例子
-5.0
-5.0的二进制形式为-101.0,相当于-1.01*2^2。
根据公式可得S=1,M=1.01,E=2。
上面我们求得S,M,E,就是浮点数在内存中得存储方式。
且IEEE 754规定:
对于32位浮点数(float),最高的一位存储符号位S,接着8位存储指数E,剩下的23位存储有效数字M。如下图

对于64位浮点数(double),最高的一位存储符号位S,接着11位存储指数E,剩下的 52位存储有效数字M。如下图

2.浮点数存的过程

IEEE 754 对有效数字M和指数E,还有一些特别的规定。

前面我们说过,M是大于等于1且小于2的,也就是说M总是写成1.xxxxx的形式,其中xxxxx表示小数部分。IEEE 754 规定 再存储有效数字M的时候只存储其xxxxx小数部分,因为其整数部分被默认为1了。 比如当M=1.01时,我们只将01存储到内存中,等到读取的再将1补上去就行了。这样做的目的是节省一位有效数字位,让其精确度更高。这样我们就清楚了为什么float被称作单精度浮点数,double被称为双精度浮点数了,因为double类型的浮点数在存储时的精确度更高。

至于指数E,情况就有颠覆炸。

首先,规定E是一个无符号整数

这就意味着,如果E为8位,它的取值范围0~255,如果E为11位,它的取值范围0~2047。

但是我们知道,在科学计数法中,指数E是可以为负数的。所以 IEEE 754 规定E在存储到内存的过程中要加上一个中间数。

对于8位的E,中间数位127。对于11位的E,中间数为1023。

例如:2^10的E=10,所以保存成32位浮点数的时候,要加上127,变成137,即10001001。

3.浮点数取的过程

指数E在内存中取出可以分成三种情况。

E不全为0或不全为1

这种情况就属于一种正常情况。我们只要将E减上127或者1023,得到真实值,再将有效数字M前加上1。ru

比如:0.5

0.5的二进制为0.1,由于规定正数部分必须为1,则写成1.0*2^-1。

则E= -1+127=126,表示为01111110,尾数部分要去掉整数部分1,为0,又因为M要存到23位,则补0,则二进制表示形式为: 0 01111110 00000000000000000000000  如下图

这也是其在内存中存储的形式。

上面是0.5存储到内存中的过程。

我们的时候取出来,发现其E不全为0或不全为1,我们将浮点数从内存中取出来的步骤和存进去的步骤相反 E为01111110 ,转换为10进制为 126,再用126-127= -1,然后将M的整数部分1补上去。最终得到 (-1)^0*1.0*2^-1,计算的0.5。

E全为0时

当E全为0时,真实E就是一个非常小的数字了,因为前面我们说过E在存入内存中,要加上一个中间数127或者1023,如果加上这个中间数E在内存中还为0的话,E的真实值为1-127或1-1023了,这时E就是一个非常小的数字了,这时也不会将M的整数部分1不上去了,这时,原来的浮点数就是一个非常逼近0的数字了,一般情况下都会默认等于0。

E全为1

当E全为1时,则表示原数无穷大。

比如算32位浮点数时,真实E为255-127=128。然而2的32次方就已经42亿多了,更别提2的128次方了。

练习题

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;
}

看到题,不要慌张,我们要冷静分析。

首先,我们创建了一个变量n,n的值为9,you

写成其二进制形式: 00000000000000000000000000001001

后来又创建了一个float 类型的指针存储了n,这时内存已经将n看作一个浮点数存储在内存中了,

这时内存中默认存的是浮点数了,将原来的二进制看成浮点数的形式,观察发现E全为0,所以当以%f 的形式打印时,会默认为0。

接着分析,

后来有对pfloat指针进行解引用,将9.0赋值给指针 。

由于是直接将9.0存储到float类型中,这时候直接用浮点数存储到内存中的方式。

将9.0转换为二进制:1001.0

在写成科学计数法的形式:1.001*2^3。由此得到 S=0,M=1.001,E=3

由于是计算的是32位浮点数,E要加上127,得到130,130的二进制表示形式位:10000010,然后M要去掉整数部分得001,因为M要存23位,在001后面补20个0。

得到完整形式为0 10000010 00100000000000000000000

这就是此时9.0在内存中的存储形式。

当后面以%d形式打印时,要以有符号整型的形式打印,这时上面的二进制就会被认作是9.0的补码,由于无符号数的原码,反码,补码相同,由上面二进制计算可得应该是一个非常大的数字。

当以%f的的格式化打印时,上面的二进制就是浮点数的存储形式的,原来是9.0,打印时也是9.0

运行代码,如下图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/598311.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯第十四届C++C组

目录 三国游戏 填充 翻转 【单调队列优化DP】子矩阵 【快速幂、欧拉函数】互质数的个数 【tire树】异或和之差 【质因数分解】公因数匹配 子树的大小 三国游戏 题目描述 小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X, Y, Z (一开始可以认为都…

python应用-计算两个日期的时间差

学习目录 1. 安装deteutil包 2. 导入relativedelta类 3. 计算两个日期的差值 4. 计算1个日期和时间差相加后得到新的日期 之前在工作中遇到一个使用场景:需要计算两个日期之前的差值,比如相差了几年几月几日,查找资料发现deteutil包的rel…

记一次农业工程学报投稿流程与感悟

经过数段时间的实验与熬夜,终于得出一个比较满意的结果,本想着第一篇先随便发一个试试投稿流程,但是经过老师修改后非让投农业工程学报,然后在网上查了一些信息后有点害怕,大致都是在说周期长,审稿慢等等 …

《QT实用小工具·十七》密钥生成工具

1、概述 源码放在文章末尾 该项目主要用于生成密钥,下面是demo演示: 项目部分代码如下: #pragma execution_character_set("utf-8")#include "frmmain.h" #include "ui_frmmain.h" #include "qmessag…

Java实现二叉树(上)

1.树型结构 1.1树型结构的概念 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看 起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 1.2树型结构的特点…

原型变量、原子操作、原子性、内存序

一、原子变量、原子操作 锁竞争:互斥锁、条件变量、原子变量、信号量、读写锁、自旋锁。在高性能基础组件优化的时候,为了进一步提高并发性能,可以使用原子变量。性能:原子变量 > 自旋锁 > 互斥锁。 操作临界资源的时间较长…

【leetcode】 c++ 数字全排列, test ok

1. 问题 2. 思路 3. 代码实现 #if 0 class Solution { private:vector<int> path; // 满足条件的一个结果 vector<vector<int>> res; // 结果集 void backtracking(vector<int> nums, vector<bool> used){// 若path的个数和nums个数相等&…

K8S基于containerd做容器从harbor拉取镜

实现创建pod时&#xff0c;通过指定harbor仓库里的镜像来运行pod 检查&#xff1a;K8S是不是用containerd做容器运行时&#xff0c;以及containerd的版本是不是小于1.6.22 kubectl get nodes -owide1、如果containerd小于 1.6.22&#xff0c;需要先升级containerd 先卸载旧的…

金三银四面试题(十六):MySQL面试都问什么(1)

在开发岗位面试中&#xff0c;MySQL基本是必考环节。所以接下来我们就进入MySQL八股文环节&#xff0c;看看都有哪些高频考题。 MySQL 中有哪些不同的表格&#xff1f; 在MySQL中&#xff0c;可以创建多种不同类型的表格&#xff0c;其中一些常见的类型包括&#xff1a; InnoD…

【边缘智能】00_边缘计算发展背景

本系列是个人学习《边缘就算基础知识入门》的笔记&#xff0c;仅为个人学习记录&#xff0c;欢迎交流&#xff0c;感谢批评指正 移动物联设备产生海量数据&#xff0c;数据密集型移动智能应用&#xff0c;计算密集、动态性高&#xff0c;实时性强 传统云计算架构 基于广域互联…

不开玩笑,你应该像「搬砖」一样写代码!斯坦福大学研究如是说

由于程序员不可避免要进行很多重复性的工作&#xff0c;并且工作强度很高&#xff0c;导致有一种自嘲的说法出现&#xff1a;程序员们自称自己每天都在搬砖&#xff08;实际上很多职场人都这么自嘲&#xff09;。我相信当我们说工作像「搬砖」的时候&#xff0c;只是在表达一种…

谷歌DeepMind发布Gecko:专攻检索,与大7倍模型相抗衡

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 Gecko 是一种通用的文本嵌入模型&#xff0c;可用于训练包括文档检索、语义相似度和分类等各…