浮点数在内存中的存储

news2025/1/12 18:19:54

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C语言学习分享⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多C语言知识
  🔝🔝


在这里插入图片描述


浮点数在内存的存储

  • 1. 前言🚩
  • 2. 浮点数存储与整型存储的关系🚩
  • 3. 浮点数存储规则🚩
  • 4. IEEE 754特殊规则🚩
  • 5. 从内存中取出E的情况🚩
  • 6. 对前面代码的解释🚩
  • 7. 总结🚩


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

大家可以猜想一下这段代码会打印什么?我们很容易判断出第一个打印以整型形式打印整型应该就是打印9,我们的第四个打印同理,以浮点型的形式打印浮点数应该是打印9.000000

在这里插入图片描述
但是我们发现中间两个打印很不符合逻辑,一个打印的是0,还有一个打印了很大的数,也可能是打印的随机值,到这里我们可能已经知道了浮点数在内存中的存储规则和整型是完全不一致的,整型的存储补码在内存中,并且分为有符号位整型和无符号位整型,那么浮点数是怎样存储的?


3. 浮点数存储规则🚩

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

  • (-1)^S * M * 2^E
  • (-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
  • M表示有效数字,大于等于1,小于2。
  • 2^E表示指数位。

这个规则是什么意思呢?我们举个例子,比如这里有一个浮点数为 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。

在这里插入图片描述

这里我们就用32位机器来做讲解,我们知道float类型占四个字节.也就是32个bit位(也就是占32个二进制位),S只占一个bit位,因为S要么是1要么是0,它只用来表示浮点数的正负.E占八个bit位,它最大能存储的是255.M的话是占23个bit位.

4. IEEE 754特殊规则🚩

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。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

懂了这些规则,我们前面距离的5.5浮点数在内存中的存储就应该是这样的:

在这里插入图片描述


5. 从内存中取出E的情况🚩

指数E从内存中取出还可以再分成三种情况:

  1. E不全为0或不全为1

这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
比如:
0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.02(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:

0 01111110 00000000000000000000000
  1. E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。

  1. E全为1

这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)


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


在这里插入图片描述

  • 我们首先来看第二个打印信息,n现在是以整数的形式存储在内存中,它在内存中的补码是
    00000000 00000000 00000000 00001001
    但是我们打印信息时,是要将它以浮点数的形式打印出来,所以我们要以浮点数的形式翻译这一段二进制代码,我将它分为浮点数的存储形式方便观察:
    0 00000000 00000000000000000001001
    我们可以发现,存储E的八个bit位全为0,当E全为0时,相当于它的值等于 (-1)S * M * 2-126,这个值是很小的,float类型的小数点后面六位都是发现不了有效数的,所以这里打印0.000000

  • 接下来再来看第三个打印信息,这里我们把指针解引用后将浮点数9.000000存入内存,这里因为存储的是浮点数,所以在内存中以浮点数的存储规则来生成这32个bit位:(-1)0 * 1.001 * 23
    0 10000010 00100000000000000000000
    其中,存储E的八个bit位是3+127=130的二进制形式.当我们打印信息时,是按%d打印,也就是按照整型的形式打印,所以编译器在取出数据时是以取出整型的方式来翻译的,我把它写成规范式
    01000001 00010000 00000000 00000000
    我们再在程序员计算器算出这段二进制代码的十进制形式:


在这里插入图片描述

和最后的结果保持了一致,我们的分析是正确的!

7. 总结🚩

浮点数在内存中的存储与整型的存储是有差异的,这一节的内容不需要大家全部背下来,你只要大致知道浮点数在内存中的存储是怎么回事就行了.看见类似于上面第一步的代码你也要能解释出来

🔎 C语言高阶 🔍

  1. 这里5.5转为二进制为什么是101.1?首先整数位的5转换为101是没有问题的,而0.5实际上是这样来的:二进制的0.1实际上是写成了1×2-1=0.5.就像101转换为10进制是写做1×22+0×20+1×20=5.这里的小数也按照这个规则来操作 ↩︎

  2. 我们知道十进制的1011可以转换成1.011×103,而我们这里的101.1是二进制数,转换成1.011×22,底数2代表这里是二进制数,指数2代表小数点向左移动了两位 ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3+WebRTC拉流(正确姿势)

vue3WebRTC拉流&#xff08;正确姿势&#xff09; 文章目录 vue3WebRTC拉流&#xff08;正确姿势&#xff09;缘由一、webRtc拉流是什么&#xff1f;1.实时通信&#xff1a;2.网络穿越&#xff1a;3.媒体处理&#xff1a;4.数据通道&#xff1a;5.使用场景: 二、使用webRtc引用…

《priority_queue的模拟实现》

本文主要介绍 文章目录 一、仿函数1.1 仿函数的定义1.2 普通仿函数1.3 需要自己实现仿函数 二、priority_queue的模拟实现 一、仿函数 1.1 仿函数的定义 所谓的仿函数(functor)&#xff0c;是通过重载()运算符模拟函数形为的类。 因此&#xff0c;这里需要明确两点&#xff1…

纯干货:数据库连接耗时慢原因排查

背景 最近公司的社区相关的服务需要优化&#xff0c;由于对业务不熟悉&#xff0c;只能借助监控从一些慢接口开始尝试探索慢的原因。由于社区相关的功能务是公司小程序流量入口&#xff0c;所以相应的服务访问量还是比较高的。针对这类高访问的项目&#xff0c;任何不留神的地…

中睿天下参编的《中国网信产业桔皮书-数据安全》正式发布

5月28日&#xff0c;2023中关村论坛中关村国际技术交易大会第七届中国网信产业前锋汇成功举办&#xff0c;本次会议以“全球数字经济发展与数据安全关键技术”为主题&#xff0c;会议由中国&#xff08;中关村&#xff09;网络安全与信息化产业联盟主办&#xff08;以下简称联盟…

芯片的XIP与BootRom启动方式

XIP&#xff1a;execute in place&#xff0c;就地执行&#xff0c;即芯片内执行&#xff0c;指应用程序可以直接在flash闪存中取指然后译码、执行&#xff0c;不必再把代码读到系统RAM中&#xff0c;flash内执行时指Nor flash不需要初始化&#xff0c;可以直接在flash内执行代…

Elsevier期刊中,撰写Author Statement

Author Statement或Authorship Contribution通常指作者声明&#xff0c;用于声明当前学术论文中每位作者的贡献。 大部分期刊都要求作者在首次投稿的时候就添加这部分内容&#xff0c;也有一些仅要求在发表之前提交。作者声明指导与模板有些学术期刊会专门提供具体的作者声明模…

Vue3 mixin 自定义指令 teleport

文章目录 Vue3 mixin & 自定义指令 & teleportmixin 混入简单使用 自定义指令简单使用全局注册参数 teleport 传送门简单使用 Vue3 mixin & 自定义指令 & teleport mixin 混入 mixins 选项接受一个 mixin 对象数组。这些 mixin 对象可以像普通的实例对象一样…

【企业化架构部署】Apache网页优化

文章目录 一、Apache网页优化概述1.优化内容2.网页压缩2.1gzip概述2.2作用2.3Apache的压缩模块概述mod_gzip模块与mod_deflate模块 3.配置网页压缩功能3.1启用网页压缩功能步骤3.2具体操作步骤 4.配置网页缓存功能4.1启用网页压缩功能步骤4.2具体操作步骤 二、Apache安全优化1.…

【JVM】.class类文件是如何被加载的?

一、类加载过程 .class文件最终加载到JVM并使用整体步骤及图示如下&#xff1a; 每个步骤所做的事情如下&#xff1a; 1、加载 &#xff08;1&#xff09;通过一个类的全限定名来获取该类文件的二进制字节流&#xff1b;&#xff08;读取class文件到内存中&#xff09; &am…

点击这里!解锁海量数据在openGauss Developer Day 2023的高光时刻

5月26日&#xff0c;openGauss Developer Day 2023在此起彼伏的掌声中圆满落幕。最前沿的核心产品、最深度的专业解读、最全面的落地案例......海量数据在此次盛会上时时高光&#xff0c;事事精彩&#xff0c;尤其是在专场分论坛上&#xff0c;数据库领域各路精英济济一堂&…

linuxOPS基础_linux文件检索及筛选

find命令 查找文件 主要功能&#xff1a;当我们查找一个文件时&#xff0c;必须使用的一个命令。 find 搜索路径 [选项]选项选项说明-name指定要搜索文件的名称&#xff0c;支持*星号通配符&#xff08;Shift 8&#xff09;-type代表搜索的文件类型&#xff0c;f代表普通文件…

使用开源代码和开源软件如何选择开源许可证

常用的开源许可证 世界上的开源许可证大约有近百种&#xff0c;如何使用开源代码和开源软件并正确理解、遵守这些开源许可证赋予的权利和义务是个比较繁琐的问题&#xff0c;我们对其中主要的六种许可证GPL、BSD、MIT、Mozilla、Apache和LGPL做个简单的梳理&#xff0c;对比一下…

什么是企业移动化管理 (EMM)

什么是EMM或企业移动化管理 企业移动化管理 &#xff08;EMM&#xff09; 是组织用来保护公司拥有和员工拥有的移动设备上的敏感公司数据的一组策略和做法。Mobile Device Manager Plus 是一个全面的 EMM 解决方案&#xff0c;允许 IT 团队和管理员跨多个平台管理设备&#xf…

推进产业发展健全服务体系,中国信通院数字员工评测工作正式启动

数字技术与应用正在快速重塑全新的经济发展格局&#xff0c;创新应用人工智能、大数据、云计算等新兴技术是企业实施数字化转型的重要策略之一。 “数字员工”是数字生产力与创造力体系的核心要素&#xff0c;自动化、智能化的执行模式将成为企业业务运营的新常态。随着数字员…

外包实在是太坑了,划水三年,感觉人都废了

先说一下自己的情况&#xff0c;专科生&#xff0c;19年通过校招进入杭州某个外包软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…

革命性3D打印数据处理软件 CHITUBOX Pro 1.3.0 Crack

CHITUBOX PRO登场 革命性的3D打印数据处理软件&#xff0c;让你发挥3D打印的无限潜力 支持多种主流CAD文件格式 除了传统的stl和obj文件&#xff0c;CHITUBOX Pro还支持导入各种主流的CAD文件格式&#xff0c;包括3ds、3mf、3dm、stp、step、wrl、x3d、sat、sab、dae、dxf、fb…

5.2.5 IP数据报(三)IP数据报的分片与重组

5.2.5 IP数据报&#xff08;三&#xff09;IP数据报的分片与重组 前面我们在学习IP数据报的格式中&#xff0c;提及了数据报的分片&#xff0c;这里我们要弄明白几个问题 为什么要分片&#xff1f; 前面我们已经解释过&#xff0c;如图 因为在数据报传送的过程中如果总长度超出…

Sui教育资助计划:共同构建Web3教育的未来

Sui教育资助计划旨在通过与社区成员一起构建公开的教育资料&#xff0c;加速推广Web3&#xff0c;并支持Sui生态系统的发展。 内容类别 包括教程、指南、视频以及文本等形式的教育材料包括学习奖励和其他体验式的教育产品&#xff0c;将学习游戏化可帮助开发人员加快构建速度…

基于matlab使用差分波束成形技术形成线性差分麦克风阵列

一、前言 本示例展示了差分波束成形的基本概念&#xff0c;以及如何使用该技术形成线性差分麦克风阵列。 二、加法与差分麦克风阵列 麦克风阵列已部署在许多音频应用中。根据布局的不同&#xff0c;麦克风阵列可分为两大类&#xff1a;加法麦克风阵列和差分麦克风阵列。附加麦克…

机器视觉陶瓷检测设备稳定性怎么样?不稳定因素有哪些?

机器视觉陶瓷检测设备是一种利用现代计算机视觉技术对陶瓷产品进行快速、高效的缺陷检测的设备。相比传统的人工检测方法&#xff0c;机器视觉陶瓷检测设备具有检测速度快、精度高、可靠性强等优点&#xff0c;可以大大提高陶瓷生产线的生产效率和产品质量。但是&#xff0c;由…