C语言进阶【5】---数据在内存中的存储【2】(小数存储很难吗?)

news2024/9/20 15:59:10

本章概述

  • 本章引要
        • 练习
  • 浮点数的存储
  • 浮点数的取出
  • 小补充
  • 题目解析
  • 彩蛋时刻!!!

本章引要

常见的浮点数:3.1415,1E10等。其中,1E10是科学计数法的形式,它也就等于1*10^10小数数据类型:float ,double ,long double

练习

在开讲本章内容前,大家先来看个代码,大家先猜一下结果:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	*pFloat = 9.0;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

结果运行图:在这里插入图片描述
不知道大家猜对多少个答案?最起码要猜对两个答案吧。

浮点数的存储

在上面的代码中,n*pFloat指的是同一个空间里面的数据,但是两者取出来的数据差别很大说明两者的存储和取出数据的方式差别很大,整形的数据存储咱们已经讲过了,现在来讲一下浮点数的存储方式。
根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:在这里插入图片描述
举个例子:

// 5.5 的二进制表示形式: 101.1
小数点前面: 1*2^2+0*2^1+1*2^0
小数点后面: 1*2^-1
小数就为:1*2^2+0*2^1+1*2^0+1*2^-1
我们知道,2^-1为0.5.
所以,小数点前面都是2的非负整数次方,小数点后面都是负整数次方。

小数存储的格式并不是我们所写的 101.1这个格式,而是按照上面的IEE754标准进行存储的。按照这个标准写的格式为:(-1)0 * 1.011* 22。其实就是个科学计数法的表现形式 。那么,按照上面的标准表示的话,S=0 ,M=1.011 ,E=2。在内存中,我们浮点数存储的有价值的数据就是S ,M和E

  • IEEE754标准规定如下
    • 对于32位的浮点数(32位机器平台),最高的1位存放的是符号位S紧跟着8位存储的是指数位E,再紧跟着的23位存储的有效值M。
    • 对于64位的浮点数(64位机器平台),最高的1位存放的是符号位S,紧跟着11位存储的是指数位E,在紧跟着52位存储的是有效值M。如图所示的存储图:在这里插入图片描述
  • IEEE754标准对E和M有些特殊规定:
    • M的特殊规定:由IEEE754标准规定,1<=M<2,也就是说所有的浮点数有效值位M必须是 1.xxxxxxx。其中 .xxxxx是小数位。IEEE754标准规定,在计算机中,对于有效值位M,只存储小数部分,整数部分的1省略(不进行存储)当读取数据的时候,再把1给加上。这样做,可以扩大小数的存储范围,使存储的精度增高
    • E的特殊规定由IEEE754标准规定的指数E是一个无符号整数(unsigned char类型),因为在浮点数的存储中,只有一个符号位,没有第二个符号位,所以,除了高位1位的符号位,剩下的全是数值位——E为无符号整形。在32位平台下的取值范围为0~255,在64位平台下的取值范围为0 ~2047.但是,我们知道,科学计数法中的指数是有负数的。比如:
0.5 的二进制表示 :0.1
IEEE754标准形式:(-1)^0*1* 2^-1
这个时候指数E就是负数 -1

为了符合科学计数的表现形式IEEE754标准规定,存入内存时,E的真实值必须再加上一个中间数,对于32位平台,这个中间数是127,对于64位平台,这个中间数是1023。比如(32位平台),2^10,E为10,我们存储的是:E+127=137,即10001001.

浮点数的取出

我们存储的是S,E和M,所以我们直接取出这三个值就OK了。然后,再按照IEEE754标准还原为小数,就可以得到我们想要的值了。对于,S和M这俩值的取出没什么特别的,正常取出就OK了,其中,别忘了取出M值的时候加上1.这里最特别的值是E,它的取值就要分三种情况讨论了,如下:

  • E不全为1或不全为0:我们取出E的值后,再减去127(32位平台)或者减去1023(64平台),才能得到真正的指数E(上面讲过了E的存储)。比如,0.5的存储。
0.5的二进制位 :0.1
IEEE745的形式:(-1)^0*1.0*2^-1    s=0 ,m=1.0 ,E=-1+127=126
0 01111110 00000000000000000000000 (小数部分全是0)
  • E全为0:当E的存储全为0的时候,IEEE745规定,原本的E=1-127=-126(32位平台)或E=1-1023(64位平台)。这个时候,有效值M不在加1,这样做是为了表示0或接近0的很小很小的小数。如下所示:。
0 00000000 00100000000000000000000
  • E全为1:这个时候说明这个小数是个很大很大的数。(正负取决于符号位S),如下所示:
0 11111111 0010000000000000000000

小补充

前面,咱们举的小数都是较容易表示二进制的。假如,我们举个较难表示的小数:5.54

5.5还是比较容易表示的 :101.1 
但是,0.04要怎样表示呢?2^-2结果是0.25,比0.04大太多了
					  2^-3结果是0.125 ,比0.04大。
					  ………………

从上面的例子中,我想告诉大家的是:浮点数在内存中是无法精确存储的。所以,对于那些较难表示的小数,计算机会在后面多输出几位(或着四舍五入),以便接近你想要的数据

题目解析

上面讲了很多的知识铺垫了,咱们也该回归开头的那个练习题了。。

int n=9;
float *pFloat = (float *)&n;
printf("*pFloat的值为:%f\n",*pFloat);
9的存储: 00000000 00000000 00000000 00001001
当执行到这个代码的时候 printf("*pFloat的值为:%f\n",*pFloat);就会把9的存储格式
当成小数的存储格式(数据类型的意义)
    S    E            M
即  0 00000000 0000000000000000000100
是E全为0的情况,有效值M不再加1,所以是个接近0的小数,又因为在32位平台下,输出小数点后6位,
所以输出结果:0.000000
//----------------------------------------//
*pFloat = 9.0;
 printf("num的值为:%d\n",n);
 9.0的存储格式: 1001.0
               (-1)^0*1.0010*2^3         E=3+127=130
               S       E               M
               0  10000010 00100000000000000000000
执行到这个代码的时候 printf("num的值为:%d\n",n);就会被当成有符号整数(数据类型的意义)
即   01000001 00010000 00000000 00000000 (正整数:原码,反码和补码相同)
输出结果:1091567616

彩蛋时刻!!!


https://www.bilibili.com/video/BV1Zd4y1A7yc/?spm_id_from=333.337.search-card.all.click&vd_source=7d0d6d43e38f977d947fffdf92c1dfad
在这里插入图片描述
每章一句感到累的时候,请抬头看看天空。感谢你能看到这里,点赞+关注+收藏+转发是对我最大的鼓励,咱们下期见!!!

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

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

相关文章

块匹配算法简介(上)

图像中的运动估计方法大致分为两类:光流法和块匹配算法(BMA,Block Matching Algorithm)。本文将介绍BMA的相关内容,包括基本原理、相似度计算准则与常见的几种搜索方法,如三步法、四步法、钻石搜索法等。 1. 背景 视频中相邻帧往往存在大量的相似内容,即只有局部的一些…

【CustomPainter】渐变圆环

说明 实现一个渐变圆环&#xff0c;起点位置为- π / 2。 效果 源码 GradientCircularPainter1 class GradientCircularPainter1 extends CustomPainter {final double progress;GradientCircularPainter1(this.progress);overridevoid paint(Canvas canvas, Size size) {c…

零基础到项目实战:Node.js版Selenium WebDriver教程

在当今数字化时代&#xff0c;Web应用程序的质量和性能至关重要。为了确保这些应用的可靠性&#xff0c;自动化测试成为一种不可或缺的工具。Selenium&#xff0c;作为自动化测试领域的瑰宝&#xff0c;为我们提供了无限可能。本教程将深入介绍Selenium&#xff0c;以及如何结合…

如何删除EXCELL文件中的空行?

1&#xff0c;选择某一列 2&#xff0c;点击《开始》《查找和选择》>《定位条件》&#xff0c;调出《定位条件》的选择框&#xff1b; 3&#xff0c;在定位条件选项框&#xff0c;选择《空值》&#xff1b; 4&#xff0c;找到变灰被选中的某一行&#xff0c;右击《删除》 5&…

配置管理之configmap

一 、云原生要素——配 置分离 ConfigMap&#xff1a;存储明文配置 Secret&#xff1a;存储密文、敏感配置、用户重要信息和密码 等。 配置更新直接同步容器&#xff0c;热加载&#xff0c;无需重启pod或者容 器;镜像和配置分离&#xff0c;可单独修改发布 二、ConfigMap 1.…

详细分析Pytorch中的register_buffer基本知识(附Demo)

目录 1. 基本知识2. Demo3. 与自动注册的差异3.1 torch.nn.Parameter3.2 自动注册子模块3.3 总结 1. 基本知识 register_buffer 是 PyTorch 中 torch.nn.Module 提供的一个方法&#xff0c;允许用户将某些张量注册为模块的一部分&#xff0c;但不会被视为可训练参数。这些张量…

2区“发稿大户”!SCISSCI双检,3天上线出版,在这里,不用担心创新性不足~

【SciencePub学术】眼瞅评职晋升最后期限就在眼前&#xff0c;小编今天就给大家带来了一本“百发百中”的救命神刊~ 01 期刊详情 【期刊简介】IF&#xff1a;2.0-3.0 JCR2区中科院4区 【出版社】MDPI出版社 【自引率】8.30% 【类别】医学 【INDEX】SCIE&SSCI在检 02…

es由一个集群迁移到另外一个集群es的数据迁移

迁移es的数据 改下index的索引 就可以了。 查询 用curl -u就可以查询了

[数据集][目标检测]不同颜色的安全帽检测数据集VOC+YOLO格式7574张5类别

重要说明&#xff1a;数据集里面有2/3是增强数据集&#xff0c;请仔细查看图片预览&#xff0c;确认符合要求在下载&#xff0c;分辨率均为640x640 数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件…

微店商品列表API接口实战指南

微店商品列表数据接口是一种允许开发者在其应用程序中调用微店店铺所有商品数据的 API 接口。通过这个接口&#xff0c;开发者可以获取到微店店铺内所有商品的信息&#xff0c;包括但不限于商品的 ID、标题、价格、库存、销量、详情描述、图片等。以下是对微店商品列表数据接口…

如何确保Java程序分发后不被篡改?使用JNI对Java程序进行安全校验

前言 众所周知&#xff0c;Java/Kotlin编译后会编译成smali&#xff0c;使用Jadx这类的反编译工具或者Hook工具就能很轻松的把我们的软件安全校验给破解了。 为了防止这种情况发生&#xff0c;我们一般会将核心代码使用C编写&#xff0c;然后使用JNI技术&#xff0c;使用Java…

TCP报文格式

RFC9293协议规范&#xff0c;规定的TCP格式如图1&#xff0c; 对比RFC793规定的格式&#xff0c;控制位从6bit变成了8bit 图1&#xff0c;图片来源&#xff1a;datatracker.ietf.org 图2为&#xff0c;可对照的中文版TCP格式&#xff0c;中文版参照的是RFC793 图2 重点…

htop 命令:系统状态监控

一、命令简介 ​htop ​是一个互动式的进程查看器&#xff0c;它是 top ​命令的增强版本&#xff0c;提供了更丰富的功能和更好的用户界面。htop ​显示了系统的实时进程和资源使用情况&#xff08;比如 CPU 和 memory 占用情况&#xff09;&#xff0c;允许用户进行交互式操…

基于Ubuntu的ECS实例实现OSS反向代理

阿里云OSS的存储空间&#xff08;Bucket&#xff09;访问地址会随机变换&#xff0c;您可以通过在ECS实例上配置OSS的反向代理&#xff0c;实现通过固定IP地址访问OSS的存储空间。 背景信息 阿里云OSS通过Restful API方式对外提供服务。最终用户通过OSS默认域名或者绑定的自定…

掌握Spring Boot数据库集成:用JPA和Hibernate构建高效数据交互与版本控制

在现代应用开发中&#xff0c;数据库操作是核心环节之一。Spring Boot提供了简化数据库集成的强大工具&#xff0c;而JPA&#xff08;Java Persistence API&#xff09;和Hibernate是两种非常流行的ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;可以帮助我们将对象…

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】 适用于:V200R008至V200R019C00版本的AC,以及有空闲以太网口的AP。 说明:本示例基于“直连二层组网直接转发【AP+AC+出口网关】”场景来介绍如何增加AP下行口有线接入。 业务需求…

Vue使用代理方式解决跨域问题

1、解决跨域问题 如果 Vue 前端应用请求后端 API 服务器&#xff0c;出现跨域问题&#xff08;CORS&#xff09;&#xff0c;如下图&#xff1a; 解决方法&#xff1a;在 Vue 项目中&#xff0c;打开 vue.config.js 配置文件&#xff0c;在配置文件中使用代理解决跨域问题。 …

怎么找到抖音爆款内容,进行扩散传播?

企业如果想做好抖音平台的品牌营销&#xff0c;需要时刻监测抖音爆款内容并进行加热放大&#xff0c;据此快速创新和改进内容&#xff0c;才能短期提高品牌相关内容的曝光量&#xff0c;快速拉升品牌声量。怎么去找到抖音的爆款内容或者是值得品牌关注的优质内容&#xff0c;主…

印尼有几百种语言,初学者要怎么开始学习?《印尼语翻译通》app或许可以帮助你!印尼语零基础入门学习。

快速翻译&#xff0c;准确高效 采用最新技术&#xff0c;提供精准翻译。翻译结果符合中国人习惯。 体验印尼文化 学习地道印尼语&#xff0c;贴近当地文化。 旅游和工作的好帮手 提供旅游和商务用语&#xff0c;沟通无障碍。 学习印尼语的良师 文本和语音翻译&#xff0c;…

Spark-RDD持久化

一、Spark的三种持久化机制 1、cache 它是persist的一种简化方式&#xff0c;作用是将RDD缓存到内存中&#xff0c;以便后续快速访问&#xff0c;提高计算效率。cache操作是懒执行的&#xff0c;即执行action算子时才会触发。 2、persist 它提供了不同的存储级别&#xff0…