[c语言日寄]浮点数在内存中的储存

在这里插入图片描述

【作者主页】siy2333
【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是进阶开发者,这里都能满足你的需求!
【食用方法】1.根据题目自行尝试 2.查看基础思路完善题解 3.学习拓展算法
【Gitee链接】资源保存在我的Gitee仓库:https://gitee.com/siy2333/study


文章目录

  • 前言
  • 1. 题目引入
  • 2. 功能介绍
    • 2.1 浮点数的基本概念
    • 2.2 IEEE 754标准
    • 2.3 浮点数的存储格式
      • 组成成分
      • 内存映射
    • 2.4 浮点数的表示范围
  • 3. 注意事项
    • 3.1 精度问题
    • 3.2 特殊值
    • 3.3 比较浮点数
  • 4. 题目解答
    • 代码分析
  • 总结


前言

在计算机科学中,浮点数是一种用于表示实数的数据类型。与整数不同,浮点数可以表示非常大或非常小的数值,并且能够处理小数部分。然而,浮点数在内存中的存储方式与整数有很大的不同,本文将深入探讨浮点数在内存中的存储方式,帮助读者更好地理解这一概念。


1. 题目引入

我们先看这样一个案例,观察一下程序运行的结果:

#include<stdio.h>

int main() {

	int n = 9;
	float* p_float = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*n_float的值为:%f\n", *p_float);

	*p_float = 9.0;

	printf("n的值为:%d\n", n);
	printf("*n_float的值为:%f\n", *p_float);

	return 0;
	}

请添加图片描述
第一个输出结果比较易懂,但是为什么另外三个的值会是这样的呢?

2. 功能介绍

2.1 浮点数的基本概念

浮点数是一种用于表示实数的数据类型。它由两部分组成:尾数M(mantissa)和指数E(exponent)。尾数表示数值的有效数字,而指数表示数值的缩放比例。通过这种方式,浮点数可以表示非常大或非常小的数值。

2.2 IEEE 754标准

IEEE 754是浮点数表示的国际标准,定义了浮点数在内存中的存储格式。根据IEEE 754标准,浮点数可以分为单精度(32位)和双精度(64位)两种类型。单精度浮点数使用32位存储,其中1位用于符号,8位用于指数,23位用于尾数。双精度浮点数使用64位存储,其中1位用于符号,11位用于指数,52位用于尾数。

2.3 浮点数的存储格式

组成成分

在IEEE 754标准中,浮点数的存储格式如下:

  • 符号位(Sign Bit):1位,表示浮点数的正负。0表示正数,1表示负数。
  • 指数位(Exponent):8位(单精度)或11位(双精度),表示浮点数的指数部分。指数部分采用偏移量表示法,即实际指数值为存储值减去一个固定的偏移量。
  • 尾数位(Mantissa):23位(单精度)或52位(双精度),表示浮点数的尾数部分。

举个例子,9.5(单精度)在内存中的内容要通过以下方式计算:

  1. 将整数和小数部分转化为二进制数:1001.1(注意,小数点后的1代表2^0.1,即0.5);
  2. 移动小数点使其变成1.xxxxx的形式:原式 = 1.0011 x 2^3
  3. 此时,尾数部分就是小数点后面的部分,即M = 0011
  4. 指数部分为2^后面的部分,也就是3,加上常数127,得到值130,转换为而二进制:E = 10000010
  5. 由于9.5为正数,所以符号位为0,即S = 0
  6. 我们将其按照S-E-M的顺序补位,得到:0-1000 0010-0000 0000 0000 0000 0000 011
  7. 也就是说,9.5在内存中的储存内容就是01000001000000000000000000000011

内存映射

单精度和双精度的内存映射如下:在这里插入图片描述

2.4 浮点数的表示范围

由于浮点数的存储方式,其表示范围受到指数和尾数的限制。

  • 单精度浮点数的表示范围约为±3.4×10^38^;
  • 双精度浮点数的表示范围约为±1.8×10^308^

然而,浮点数的精度受到尾数位数的限制,单精度浮点数的精度约为7位十进制数,双精度浮点数的精度约为15位十进制数。

3. 注意事项

3.1 精度问题

浮点数的精度受到尾数位数的限制,因此在处理非常大或非常小的数值时,可能会出现精度损失。例如,两个非常接近的浮点数相减可能会导致结果不准确。为了避免这种情况,可以使用更高精度的浮点数类型(如双精度浮点数)或采用数值稳定的算法。

我们看下面的代码:

#include<stdio.h>

int main() {

	float a = 3.14;
	printf("%f", a);

	return 0;
}

我们在调试中查看a在内存中的值
在这里插入图片描述
其中04 84 5f 3c转换成二进制为0-10010000-1000 1011 1110 0111 100
不难发现,3.14的小数部分无法被精确表示,因为每一个位数,都是2的n次方:2-1、2-2 、2-3……

3.2 特殊值

IEEE 754标准定义了一些特殊值,如正无穷大(+∞)、负无穷大(-∞)和非数字(NaN)。这些特殊值用于表示某些特殊情况,如除以零或无效运算。

3.3 比较浮点数

由于浮点数的精度问题,直接比较两个浮点数是否相等可能会导致错误的结果。通常,可以使用一个很小的阈值(如ε)来判断两个浮点数是否近似相等。例如,判断|a - b| < ε是否成立,而不是直接判断a == b。

4. 题目解答

代码分析

  1. 变量声明与初始化

    int n = 9;
    float* p_float = (float*)&n;
    
    • int n = 9; 声明了一个整数变量 n 并将其初始化为 9
    • float* p_float = (float*)&n; 声明了一个指向浮点数的指针 p_float,并将其初始化为指向 n 的地址。这里使用了类型转换 (float*),将 n 的地址(原本是 int* 类型)强制转换为 float* 类型。
  2. 第一次输出

    printf("n的值为:%d\n", n);
    printf("*n_float的值为:%f\n", *p_float);
    
    • printf("n的值为:%d\n", n); 输出 n 的值,此时 n 的值是 9,所以输出为 n的值为:9
    • printf("*n_float的值为:%f\n", *p_float); 输出 p_float 所指向的值。由于 p_float 是一个 float* 类型的指针,而 n 是一个 int 类型的变量,*p_float 会将 n 的内存内容解释为一个浮点数。
  • n此时在内存中的值为:00000000-00000000-00000000-00001001
  • 按照浮点类型解释:0-00000000-00000000000000000001001,是一个非常小的数。
  1. 修改指针指向的值

    *p_float = 9.0;
    
    • *p_float = 9.0;p_float 所指向的内存位置的值修改为 9.0。由于 p_float 指向的是 n 的内存地址,因此 n 的内存内容被修改为浮点数 9.0 的二进制表示。
  2. 第二次输出

    printf("n的值为:%d\n", n);
    printf("*n_float的值为:%f\n", *p_float);
    
    • printf("n的值为:%d\n", n); 输出 n 的值。由于 n 的内存内容被修改为浮点数 9.0 的二进制表示,因此 n 的值现在是一个与 9.0 的二进制表示相对应的整数。同理,这个值是一个非常大的整数。
    • printf("*n_float的值为:%f\n", *p_float); 输出 p_float 所指向的值。由于 p_float 指向的内存内容已经被修改为 9.0,因此输出为 *n_float的值为:9.000000

总结

浮点数在内存中的存储是一个复杂的过程。本文详细介绍了浮点数的基本概念、IEEE 754标准、存储格式、表示范围、精度问题等。希望通过本文的介绍,读者能够更好地理解这一知识点。

关注窝,每三天至少更新一篇优质c语言题目详解~

[专栏链接QwQ] :⌈c语言日寄⌋CSDN
[关注博主ava]:siy2333
感谢观看~ 我们下次再见!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Yageo国巨的RC系列0402封装1%电阻库来了

工作使用Cadence多年&#xff0c;很多时候麻烦的就是整理BOM&#xff0c;因为设计原理图的时候图省事&#xff0c;可能只修改value值和封装。 但是厂家&#xff0c;规格型号&#xff0c;物料描述等属性需要在最后的时候一行一行的修改&#xff0c;繁琐又容易出错&#xff0c;过…

【文档智能】Qwen2.5-VL在版式分析和表格识别上的实际评测效果

qwen开年开源了Qwen2.5-VL系列权重模型&#xff0c;笔者观察到相较于传统的多模态系列&#xff0c;增加了文档理解功能。笔者以文档智能中两个比较重要的任务版式分析和表格识别&#xff0c;笔者直接测试下Qwen2.5-VL-72B的效果。 版式分析 case1 case2 这个case没有输出bbox…

【计算机组成原理】1_绪论

chap1 绪论 1. 国产芯片现状 MIPS阵营&#xff1a;龙芯X86阵营&#xff08;常见于桌面和服务器&#xff09;&#xff1a;兆芯&#xff08;VIA&#xff09;&#xff0c;海光&#xff08;AMD&#xff09;ARM阵营&#xff08;常见于移动嵌入式、手机平板等&#xff09;&#xff…

解锁反序列化漏洞:从原理到防护的安全指南

目录 前言 一、什么是反序列化 二、反序列化漏洞原理 三、反序列化漏洞的危害 &#xff08;一&#xff09;任意代码执行 &#xff08;二&#xff09;权限提升 &#xff08;三&#xff09;数据泄露与篡改 四、常见的反序列化漏洞场景 &#xff08;一&#xff09;PHP 反…

openGauss 3.0 数据库在线实训课程1:学习数据库状态查看

openGauss数据库状态查看 前提 我正在参加21天养成好习惯| 第二届openGauss每日一练活动 课程详见&#xff1a;openGauss 3.0.0数据库在线实训课程 学习目标 学习从操作系统层面和使用openGauss工具查看数据库的状态、版本和数据文件目录。 课程作业 gs_ctl是openGauss提…

[含文档+PPT+源码等]精品基于Python实现的django个性化健康餐计划订制系统

软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#xff1a;JavaScript、VUE.js&#xff08;2.X&#xff09;、css3 开发工具&#xff1a;pycharm、Visual Studio Code、HbuildX 数据库&#xff1a;MySQL 5.7.26&am…

单机伪分布Hadoop详细配置

目录 1. 引言2. 配置单机Hadoop2.1 下载并解压JDK1.8、Hadoop3.3.62.2 配置环境变量2.3 验证JDK、Hadoop配置 3. 伪分布Hadoop3.1 配置ssh免密码登录3.2 配置伪分布Hadoop3.2.1 修改hadoop-env.sh3.2.2 修改core-site.xml3.2.3 修改hdfs-site.xml3.2.4 修改yarn-site.xml3.2.5 …

ZooKeeper单节点详细部署流程

ZooKeeper单节点详细部署流程 文章目录 ZooKeeper单节点详细部署流程 一.下载稳定版本**ZooKeeper**二进制安装包二.安装并启动**ZooKeeper**1.安装**ZooKeeper**2.配置并启动**ZooKeeper** ZooKeeper 版本与 JDK 兼容性3.检查启动状态4.配置环境变量 三.可视化工具管理**Zooke…

IMX6ULL环境搭建遇到的问题和解答更新

IMX6ULL环境搭建遇到的问题 开发板&#xff1a;正点原子IMX6ULL 终端软件串口控制&#xff1a;MobaXterm 1、网络环境搭建三方互ping不通 电脑无网口&#xff0c;使用绿联USB转网口&#xff0c;接网线直连开发板&#xff0c;电脑WiFi上网 按文档设置的 IP 地址&#xff0c;以…

Windows Docker笔记-Docker拉取镜像

通过在前面的章节《安装docker》中&#xff0c;了解并安装成功了Docker&#xff0c;本章讲述如何使用Docker拉取镜像。 使用Docker&#xff0c;主要是想要创建并运行Docker容器&#xff0c;而容器又要根据Docker镜像来创建&#xff0c;那么首当其冲&#xff0c;必须要先有一个…

51单片机07 串口通信

串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信。51单片机内部自带UART&#xff08;Universal Asynchronous Recei…

外置互感器导轨式电能表

1 概述 1 Overview ADL系列导轨式多功能电能表&#xff0c;是主要针对于光伏并网系统、微逆系统、储能系统、交流耦合系统等新能源发电系统而设计的一款智能仪表&#xff0c;产品具有精度高、体积小、响应速度快、安装方便等优点。具有对电力参数进行采样计量和监测&#xff…

微软发布基于PostgreSQL的开源文档数据库平台DocumentDB

我们很高兴地宣布正式发布DocumentDB——一个开源文档数据库平台&#xff0c;以及基于 vCore、基于 PostgreSQL 构建的 Azure Cosmos DB for MongoDB 的引擎。 过去&#xff0c;NoSQL 数据库提供云专用解决方案&#xff0c;而没有通用的互操作性标准。这导致对可互操作、可移植…

开放式TCP/IP通信

一、1200和1200之间的开放式TCP/IP通讯 第一步&#xff1a;组态1214CPU&#xff0c;勾选时钟存储器 第二步&#xff1a;防护与安全里面连接机制勾选允许PUT/GET访问 第三步&#xff1a;添加PLC 第四步&#xff1a;点击网络试图&#xff0c;选中网口&#xff0c;把两个PLC连接起…

【漫画机器学习】083.安斯库姆四重奏(Anscombe‘s quartet)

安斯库姆四重奏&#xff08;Anscombes Quartet&#xff09; 1. 什么是安斯库姆四重奏&#xff1f; 安斯库姆四重奏&#xff08;Anscombes Quartet&#xff09;是一组由统计学家弗朗西斯安斯库姆&#xff08;Francis Anscombe&#xff09; 在 1973 年 提出的 四组数据集。它们…

【C语言】指针运算与数组关系:详细分析与实例讲解

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;1. 指针的基础运算1.1 指针的加减运算1.2 指针加整数与指针减整数1.3 指针与指针的运算 &#x1f4af;2. 指针的实际应用&#xff1a;模拟 strlen 函数2.1 使用指针模拟…

在线教程丨YOLO系列10年更新11个版本,最新模型在目标检测多项任务中达SOTA

YOLO (You Only Look Once) 是计算机视觉领域中最具影响力的实时目标检测算法之一&#xff0c;以其高精度与高效性深受业界青睐&#xff0c;广泛应用于自动驾驶、安防监控、医疗影像等领域。 该模型最早于 2015 年由华盛顿大学研究生 Joseph Redmon 发布&#xff0c;开创了将目…

面向对象程序设计-实验1

6-1 求两个或三个整数中的最大数&#xff0c;用带默认参数的函数实现 本题要求实现一个带默认参数的函数&#xff0c;求两个或三个整数中的最大数 代码清单&#xff1a; #include <iostream> using namespace std; int main() { int max( int a,int b,int c0); int …

如何打开vscode系统用户全局配置的settings.json

&#x1f4cc; settings.json 的作用 settings.json 是 Visual Studio Code&#xff08;VS Code&#xff09; 的用户配置文件&#xff0c;它存储了 编辑器的个性化设置&#xff0c;包括界面布局、代码格式化、扩展插件、快捷键等&#xff0c;是用户全局配置&#xff08;影响所有…

2025简约的打赏系统PHP网站源码

源码介绍 2025简约的打赏系统PHP网站源码 源码上传服务器&#xff0c;访问域名/install.php安装 支持自定义金额打赏 集成支付宝当面付 后台管理系统 订单记录查询 效果预览 源码获取 2025简约的打赏系统PHP网站源码