【C语言进阶】数据的存储----浮点型篇

news2024/9/25 9:38:28

🍁 博客主页:江池俊的博客

💫收录专栏:C语言—探索高效编程的基石
💻 其他专栏:数据结构探索
💡代码仓库:江池俊的代码仓库
🎪 社区:GeekHub

🍁 如果觉得博主的文章还不错的话,请点赞👍收藏🌟 三连支持一下博主💞

文章目录

  • 🌟浮点型在内存中的存储
  • 🌟浮点数的存储规则
  • 🌟C语言中如何``存储``浮点数?
    • 📌IEEE 754浮点数表示
    • 📌单精度浮点数(float)
    • 📌双精度浮点数(double)
  • 🌟C语言中如何``读取``浮点数?
  • 🌟练习题
    • 📌1.练习1
    • 📌2.练习2
  • 🌟总结

🌟浮点型在内存中的存储

常见的浮点数:

3.14159
1E10 = 1 × \times × 1010(即10000000000.000000)
浮点数家族包括: float、double、long double 类型。
浮点数表示的范围:float.h中定义
在这里插入图片描述

🌟浮点数的存储规则

在C语言中,浮点型数据(如float和double)在内存中的存储方式通常遵循国际标准IEEE(电气和电子工程协会) 754,这是一种用于表示浮点数的二进制标准。这个标准定义了两种常见的浮点数表示形式:单精度(float)和双精(double)。任意一个二进制浮点数V可以表示成下面的形式:

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

🌟C语言中如何存储浮点数?

📌IEEE 754浮点数表示

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的存储方式

首先,E为一个无符号整数(unsigned int)
这意味着,如果E为8位,它的取值范围为0 ~ 255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。
比如:210 的E是10,所以保存成32位浮点数时,必须保存10+127=137
即 10001001。

📌单精度浮点数(float)

对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M
在单精度浮点数中,内存结构如下:

  [S]      [E]       [M]
[符号位] [指数位] [有效数字位]
   1       8         23
  • 符号位 S(1 bit):表示正负号。

  • 指数位 E(8 bit):表示指数部分 (点击跳转到 - 指数E的存储方式)

  • 有效数字位 M(23 bit):表示小数部分,使用二进制分数表示。

图示:
在这里插入图片描述
比如:
0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0 × \times × 2-1其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:

0 01111110 00000000000000000000000

📌双精度浮点数(double)

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
双精度浮点数的内存结构如下:

  [S]      [E]       [M]
[符号位] [指数位] [有效数字位]
   1       11        52
  • 符号位 S(1 bit):表示正负号。
  • 指数位 E(11 bit):表示指数部分 (点击跳转到 - 指数E的存储方式)
  • 有效数字位 M(52 bit):表示小数部分。

图示:
在这里插入图片描述

这种内存表示方式使得浮点数可以在计算机上进行精确表示和计算,但也引入了浮点数计算中的一些挑战和限制。

🌟C语言中如何读取浮点数?

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

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

  • S:直接取出,0表示正数,1表示负数
  • E:指数E的计算值减去127(或1023),得到真实值
  • M:将有效数字M前加上第一位的1。

2. E全为0

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

3. E全为1

  • S:直接取出,0表示正数,1表示负数
  • E:指数E的计算值减去127(或1023),得到真实值
  • M:这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)

🌟练习题

📌1.练习1

在这里插入图片描述

📌2.练习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;
}

结果:
在这里插入图片描述
分析:

int main()
{
	int n = 9;
	//将 0x00000009 拆分,得到第一位符号位s=0,后面8位的指数 E=00000000 ,
    //最后23位的有效数字M=000 0000 0000 0000 0000 1001。
	//9 --> 0 00000000 00000000000000000001001 正数原码=反码=补码
	//      S    E              M
	//E全为0,所以真实值为1-127 = -126 
	//上一节第二种情况:M = 0.00000000000000000001001
	//S = 0
	//由于指数E全为0,所以符合上一节的第二种情况。因此,浮点数V就写成:
	//V = (-1)^0 * 0.00000000000000000001001 * 2^(-126) = 1.001 * 2^(-146)
	//显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。
	
	float* pFloat = (float*)&n;//n --> int*
	printf("n的值为:%d\n", n);//9
	printf("*pFloat的值为:%f\n", *pFloat);// 0.000000....(非常小的数)
	
	*pFloat = 9.0;
	//首先,浮点数9.0等于二进制的1001.0,即1.001×2^3。
	//(-1)^0 * 1.001 * 2^3
	//S = 0
	//E = 3+127 = 130
	//M = 00100000000000000000000 有效数字M等于001后面再加20个0,凑满23位
	//0 10000010 00100000000000000000000
	//S    E              M
	//这个32位的二进制数,还原成十进制,正是 1,091,567,616 。
	
	printf("num的值为:%d\n", n);//--> 1,091,567,616
	printf("*pFloat的值为:%f\n", *pFloat);//9.0
	return 0;
}

🌟总结

浮点数在计算机内部的存储方式由IEEE 754标准定义,它将浮点数分为单精度和双精度,每种表示都有符号位、指数部分和有效数字部分。了解浮点数的内存表示有助于我们更好地理解浮点数的行为,预测计算结果,并在编程中避免潜在的精度问题。在进行涉及浮点数的计算时,始终要考虑到浮点数表示可能引起的舍入误差,以获得正确的结果。

🔥今天的分享就到这里,如果觉得博主的文章还不错的话,请👍三连支持一下博主哦🤞
在这里插入图片描述

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

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

相关文章

部分常用CSS样式

目录 1.字体样式 2.文本样式 3.鼠标样式 cursor 4.背景样式 5.列表样式 6.CSS伪类 7.盒子模型 1.字体样式 font-family 字体类型&#xff1a;隶书” “楷体” font-size 字体大小&#xff1a;像素px font-weight 字体粗细&#xff1a;bold 定义粗体字…

8月5日上课内容 nginx的优化和防盗链

全部都是面试题 nginx的优化和防盗链 重点就是优化&#xff1a; 每一个点都是面试题&#xff0c;非常重要&#xff0c;都是面试题 1、隐藏版本号&#xff08;重点&#xff0c;一定要会&#xff09; 备份 cp nginx.conf nginx.conf.bak.2023.0805 方法一&#xff1a;修改配…

拦截器在SpringBoot中使用,HandlerInterceptor,WebMvcConfigurer

拦截器在Controller之前执行。 用于权限校验&#xff0c;日志记录&#xff0c;性能监控 在SpringBoot中使用 创建拦截器类&#xff1a;首先&#xff0c;创建一个Java类来实现拦截器逻辑。拦截器类应该实现Spring提供的HandlerInterceptor接口。实现拦截器方法&#xff1a;拦…

探索PostgreSQL的新功能:最新版本更新解析

PostgreSQL作为一种强大而开源的关系型数据库管理系统&#xff0c;不断在不断进化和改进。每一次的版本更新都带来了更多功能和改进&#xff0c;让用户在处理大规模数据和复杂查询时体验更好的性能和功能。在本文中&#xff0c;我们将深入探索PostgreSQL的最新版本更新&#xf…

进程上下文切换以及应用场景

各个进程之间是共享 CPU 资源的&#xff0c;在不同的时候进程之间需要切换&#xff0c;让不同的进程可以在 CPU 执行&#xff0c;那么这个一个进程切换到另一个进程运行&#xff0c;称为进程的上下文切换。 在详细说进程上下文切换前&#xff0c;我们先来看看 CPU 上下文切换 大…

VX-API-Gateway开源网关技术的使用记录

VX-API-Gateway开源网关技术的使用记录 官网地址 https://mirren.gitee.io/vx-api-gateway-doc/ VX-API-Gateway(以下称为VX-API)是基于Vert.x (java)开发的 API网关, 是一个分布式、全异步、高性能、可扩展、轻量级的可视化配置的API网关服务官网下载程序zip包 访问 https:/…

深入浅出 Typescript

TypeScript 是 JavaScript 的一个超集&#xff0c;支持 ECMAScript 6 标准&#xff08;ES6 教程&#xff09;。 TypeScript 由微软开发的自由和开源的编程语言。 TypeScript 设计目标是开发大型应用&#xff0c;它可以编译成纯 JavaScript&#xff0c;编译出来的 JavaScript …

AtcoderABC226场

A - Round decimalsA - Round decimals 题目大意 给定一个实数X&#xff0c;它最多可以使用三位小数表示&#xff0c;而且X的小数点后有三位小数。将X四舍五入到最接近的整数并打印结果。 思路分析 可以使用round函数进行四舍五入 知识点 round(x) 是一个用来对数字进行四…

SpringIoc-个人学习笔记

Spring的Ioc、DI、AOP思想 Ioc Ioc思想&#xff1a;Inversion of Control&#xff0c;控制反转&#xff0c;在创建Bean的权利反转给第三方 DI DI思想&#xff1a;Dependency Injection&#xff0c;依赖注入&#xff0c;强调Bean之间的关系&#xff0c;这种关系由第三方负责去设…

Redis 报错 RedisConnectionException: Unable to connect to x.x.x.x:6379

文章目录 Redis报错类型可能解决方案 Redis报错类型 org.springframework.data.redis.connection. spingboot调用redis出错 PoolException: Could not get a resource from the pool; 连接池异常:无法从池中获取资源; nested exception is io.lettuce.core. 嵌套异常 RedisConn…

针对高可靠性和高性能优化的1200V碳化硅沟道MOSFET

目录 标题&#xff1a;1200V SiC Trench-MOSFET Optimized for High Reliability and High Performance摘要信息解释研究了什么文章创新点文章的研究方法文章的结论 标题&#xff1a;1200V SiC Trench-MOSFET Optimized for High Reliability and High Performance 摘要 本文详…

FPGA----UltraScale+系列的PS侧与PL侧通过AXI-HP交互(全网唯一最详)附带AXI4协议校验IP使用方法

1、之前写过一篇关于ZYNQ系列通用的PS侧与PL侧通过AXI-HP通道的文档&#xff0c;下面是链接。 FPGA----ZCU106基于axi-hp通道的pl与ps数据交互&#xff08;全网唯一最详&#xff09;_zcu106调试_发光的沙子的博客-CSDN博客大家好&#xff0c;今天给大家带来的内容是&#xff0…

获取k8s scale资源对象的命令

kubectl get --raw /apis/<apiGroup>/<apiVersion>/namespaces/<namespaceName>/<resourceKind>/<resourceName>/scale 说明&#xff1a;scale资源对象用来水平扩展k8s资源对象的副本数&#xff0c;它是作为一种k8s资源对象的子资源存在&#xf…

This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in...错误解决

在创建函数的时候报错如下&#xff1a; 解决&#xff1a; 设置如下参数即可 SET GLOBAL log_bin_trust_function_creatorsTRUE;

[CKA]考试之PersistentVolumeClaims

由于最新的CKA考试改版&#xff0c;不允许存储书签&#xff0c;本博客致力怎么一步步从官网把答案找到&#xff0c;如何修改把题做对&#xff0c;下面开始我们的 CKA之旅 题目为&#xff1a; Task 创建一个名字为pv-volume的pvc&#xff0c;指定storageClass为csi-hostpath-…

面试热题(打家窃舍)

一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存放金额的非负…

宋浩概率论笔记(三)随机向量/二维随机变量

第三更&#xff1a;本章的内容最重要的在于概念的理解与抽象&#xff0c;二重积分通常情况下不会考得很难。此外&#xff0c;本次暂且忽略【二维连续型随机变量函数的分布】这一章节&#xff0c;非常抽象且难度较高&#xff0c;之后有时间再更新。

Linux系统部署Python语言开发运行环境

目录 Ubuntu自带python Debian安装python 安装 pip 库列表 安装第三方库 使用国内镜像站 实装 tkinter 库 编写运行代码 测试代码1 1. 创建项目 2. 创建源码文件 3. 写入源代码 4. 修改权限 5. 运行代码 测试代码2 本文的使用环境是Windows的Linux 子系统&…

Opencv-C++笔记 (14) : 霍夫变换(直线、圆)

文章目录 一、霍夫变换-直线1.1霍夫变换-直线 原理详解 二、霍夫圆检测 一、霍夫变换-直线 Hough Line Transform用来做直线检测 前提条件 – 边缘检测已经完成 1、平面空间&#xff08;x,y&#xff09;到极坐标空间转换&#xff1b; 2、对极坐标进行变换&#xff0c;转化为…

作为软件工程师成为全职创作者:有争议的建议

我以写作为生&#xff0c;全职。我的通讯是Substack上排名第一的付费技术通讯&#xff0c;我是一个全职的创作者。 随着远程工作在科技领域变得越来越普遍&#xff0c;我收到越来越多的人发来同样的问题&#xff1a;他们怎么能像我一样&#xff1f; 尽管我被认为是一个成功的…