C语言中整型与浮点型在内存中的存储

        今天让我们来看看整型的数据和浮点型的数据在内存中是怎么存储的呢

        整型数据在内存中的存储

        整型数据在内存中存储的是二进制的补码

        正数的话也没什么可说的,原码反码补码都相同

        我们来看看负数:

       以-5为例

        原码:10000000 00000000 00000000 00000101

        反码:11111111 11111111 11111111 11111010

        补码:11111111 11111111 11111111 11111011

        负数的反码就是符号位不变,其他位按位取反。负数的补码就是反码+1.

        为什么内存要存补码?

        在计算机系统中,数值一律使用补码的方式来表示和储存。我们使用补码的原因在于,使用补码可以将符号位和数值域统一处理。

        同时,加法和减法也可以使用补码来统一处理,因为CPU中其实只有加法器。

        此外,补码与原码相互转换,它们的运算过程是相同的,不需要额外的硬件电路去进行补码到原码的额外转换;大致情况如图:

        

        我们还是以-5为例

        原码:        10000000 00000000 00000000 00000101

        补码:        11111111 11111111 11111111 11111011

        补码取反: 10000000 00000000 00000000 00000100

        加一:        10000000 00000000 00000000 00000101

        我们通过运算可以看到,结果无误,补码取反加一之后确实可以得到原码。

        其实在我们之前的一篇博客中解释过了大小端存储,我们使用的vs2022使用的就是小端字节序存储方式。

        还是以-5为例

        

        我们通过程序的调试可以发现,在a的地址0x012ff87c中a存储的值为fb ff ff ff,那么我们再来看看-5的补码:

        补码:11111111 11111111 11111111 11111011

        十六进制为:ff ff ff fb

        十六进制数中1111(十进制为15)是f,1011(十进制为11)是b

        小端存储方式是数据的高位存储在高地址,数据的低位存储在低地址,这里也印证了我们之前的结论。        

        了解了整型在内存中的存储,我们再来看看浮点型在内存中是怎么存储的吧

        浮点型数据在内存中的存储

        在了解浮点型存储方式之前,想邀请大家来猜一猜以下的代码输出的值都是多少

        

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

        大家要好好想一想哦

        浮点型存储的标准

        既然这里这样说了,那么我们就了解浮点型与整型在内存中的存储方式肯定是不一样的了,那我们来看看浮点型存储的标准

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

        (-1)^S*M*2^E

        -1^S表示符号位,当S=0,V是正数;当S=1,V为负数。

        M表示有效数字,M表示的值大于等于1,小于2。就是将数字变为科学计数法

        2^E表示指数位

        大家是不是一脸懵逼啊,我刚刚看到的时候也是,给大家举几个例子理解一下

        假设V=5.5

        二进制表示:101.1

        在转换为2进制的时候要注意小数点之后的权重,从小数点第一位开始,往后的权重依次为2^-1,2^-2,2^-3......

        这里我们来看,有效数字M要求是大于等于1,小于2,那么我们这里就需要将101.1的小数点往前移动两位可以达到要求,那么我们这里就变为了1.011*2^2,我们这里是2进制数字,乘的底数就为2,小数点往前移几位,咋们就乘2的多少次方。

        这里我们基本上就解决了,那么我们的V应该怎么写呢

        V=5.5=(-1)^0*1.011*2^2

        S=0(数字为正数)

        M = 1.011(有效数字)

        E = 2

        IEEE 754 规定

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

        图示:

        

        对于64位的浮点数,最高一位是符号位S,接着的11位是指数E,剩下的52位为指数S。

        

       有效数字M

        有效数字M,我们M的值只能是1~2之间的话,那么我们表示M就可以使用1.xxxxxx的形式,xxxxxx表示小数部分

        IEEE 754 规定,在计算机内部保存M的时候,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。

        比如保存1.01的时候,我们可以直接保存01,等到我们需要读取的时候,再把第一位加上去。我们这样做的目的是,节省一位有效数字。以32位浮点数为例,留给M的只有23位,我们将第一位舍弃之后,就可以保存24位的有效数字

        指数E的复杂情况

        首先我们需要了解的是E的类型是unsigend int类型,它是一个无符号整数,那么这意味着,当E在单精度浮点型里为8位的时候它的取值是0~255,但是我们知道在科学计数法中,E是可以出现负数的,那么我们针对这个问题IEEE 754规定,输入内存时E的真实值必须再加上一个中间数,对于8位E,这个中间数为127,11位的话是1023。

        那么当我们要在内存中存的e为10的时候,我们需要将10+127,存放137进入内存,E=10001001。

        之后指数E从内存中取出还要分3种情况

        E不全为0或E不全为1

        这时浮点数采用以下规则表示,即指数E的计算减去127(或1023),得到真实值,之后将有效数字M前加上第一位的1.

        例如:

        0.5的二进制表示为0.1,由于规定正数部分必须为1,即将小数点右移一位,则为1.0*2^(-1),其阶码为-1+127=126,表示为:01111110,而尾数部分去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示为

        0 01111110 00000000000000000000000

        E全为0

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

        E全为1

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

        现在大家对之前的题有答案了嘛

        我们来看看

        代码运行结果

        

       疑问与下回分解

        在n=9的时候为什么*pFloat的值会是0.000000呢?为什么num的值会那么大呢?为什么在n的值为9.0 的时候*pFloat的值会是9.000000呢?

        写不动喽,我们有很多疑问,大家可以先消化一下今天的知识,我们每天再来为大家详细解释。

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

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

相关文章

Jenkins CI/CD 持续集成专题二 Jenkins 相关问题汇总

一 问题一 pod [!] Unknown command: package 1.1 如果没有安装过cocoapods-packager,安装cocoapods-packager,sudo gem install cocoapods-packager 1.2 如果已经安装cocoapods-packager,还是出现上面的错误,有可能是pod的安…

Spring Boost + Elasticsearch 实现检索查询

需求:对“昵称”进行“全文检索查询”,对“账号”进行“精确查询”。 认识 Elasticsearch 1. ES 的倒排索引 正向索引 对 id 进行检索速度很快。对其他字段即使加了索引,只能满足精确查询。模糊查询时,逐条数据扫描&#xff0c…

vscode ssh远程连接服务器,一直正在下载vscode服务器的解决办法

前言 为方便描述,在本教程中,发起远程连接的叫“主机”,被远程连接的叫“服务器”。 正文 如果主机是首次用vscode远程连接服务器,会在服务器上自动下载vscode服务器,但有时候因为网络问题,会卡在&#xff…

UE4 相机围绕某点旋转

关卡(一个相机CameraActor,一个Cube(名叫Target)): 关卡蓝图里的逻辑(为了大家看得清楚,特意连得很紧凑,也比较乱,不然一张截图放不下): 只对Yaw 只Pitch: 同样对Roll: 围绕任…

switch语句深讲

一。功能 1.选择,由case N:完成 2.switch语句本身没有分支功能,分支功能由break完成 二。注意 1.switch语句如果不加break,在一次判断成功后会执行下面全部语句并跳过判断 2.switch的参数必须是整形或者是计算结果为整形的表达式,浮点数会…

visionTransformer window平台下报错

错误: KeyError: Transformer/encoderblock_0/MlpBlock_3/Dense_0kernel is not a file in the archive解决方法: 修改这个函数即可,主要原因是Linux系统与window系统路径分隔符不一样导致 def load_from(self, weights, n_block):ROOT f&…

c++使用googletest进行单元测试

googletest进行单元测试 使用Google test进行测试一、单元测试二、使用gmock测试 使用Google test进行测试 使用场景: 在平时写代码中,我们需要测试某个函数是否正确时可以使用Google test使用,当然,我们也可以自己写函数进行验证…

云计算时代:SFP、SFP+、SFP28、QSFP+和QSFP28光纤模块详解

随着数据中心的快速发展和云计算的广泛应用,高速、高效率的光纤网络传输成为关键需求。在众多光纤模块中,SFP、SFP、SFP28、QSFP和QSFP28是最常见的几种类型。本文将为您详细解析这几种光纤模块之间的区别,帮助您更好地了解和选择适合自己需求…

网贷大数据黑名单要多久才能变正常?

网贷大数据黑名单是指个人在网贷平台申请贷款时,因为信用记录较差而被列入黑名单,无法获得贷款或者贷款额度受到限制的情况。网贷大数据黑名单的具体时间因个人信用状况、所属平台政策以及银行审核标准不同而异,一般来说,需要一定…

就业班 第三阶段(nginx) 2401--4.22 day1 nginx1 http+nginx初识+配置+虚拟主机

一、HTTP 介绍 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件…

Centos 5 的yum源

背景 有使用较老的Centos 5 系统内部安装软件无法正常报错,是由于系统叫老yum源存在问题 处理方法 更换下述yum源,可以将其他repo源文件备份移动到其他目录,添加下述源后重新测试 [C5.11-base] nameCentOS-5.11 baseurlhttp://vault.c…

微信小程序实现预约生成二维码

业务需求&#xff1a;点击预约按钮即可生成二维码凭码入校参观~ 一.创建页面 如下是博主自己写的wxml&#xff1a; <swiper indicator-dots indicator-color"white" indicator-active-color"blue" autoplay interval"2000" circular > &…

照片相似性搜索引擎Embed-Photos;赋予大型语言模型(LLMs)视频和音频理解能力;OOTDiffusion的基础上可控制的服装驱动图像合成

✨ 1: Magic Clothing Magic Clothing是一个以可控制的服装驱动图像合成为核心的技术项目&#xff0c;建立在OOTDiffusion的基础上 Magic Clothing是一个以可控制的服装驱动图像合成为核心的技术项目&#xff0c;建立在OOTDiffusion的基础上。通过使用Magic Clothing&#xf…

c# winform打包

本次采用vs2022打包winform窗体应用&#xff0c;有时应用不需要打包为安装应用&#xff0c;执行一个EXE就运行了 测试了几次&#xff0c;winform 非.net Framework 和控制台程序也是非.net Framework项目能打包这种&#xff0c;后续在研究

Redis入门到通关之数据结构解析-ZipList

文章目录 ☃️概述☃️ZipListEntry☃️Encoding编码☃️ZipList的连锁更新问题☃️总结 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与…

Python与数据库连接

新建表boss create table 创建表 Code import pymysqlcon pymysql.connect(hostlocalhost,\userroot,\password,\port3306,\dbbusiness) cursorcon.cursor() cursor.execute(create table if not exists boss(id int auto_increment primary key,name varchar(20)not null…

c++中的指针

一、指针的基本概念 指针的作用&#xff1a;可以通过指针间接访问内存 内存编号是从0开始记录的&#xff0c;一般采用16进制数字表示。可以利用指针变量保存地址。 二、指针变量的定义和使用 指针变量定义语法&#xff1a; 数据类型 * 变量名 #include<iostream> u…

穿越物联网的迷雾:深入理解MQTT协议

目录标题 1、MQTT简介核心特性 2、MQTT的工作原理通信过程 3、MQTT的消息质量&#xff08;QoS&#xff09;4、安全机制5、实践应用环境准备示例项目发布者客户端订阅者客户端 6、最佳实践7、结论8、参考资料 在物联网&#xff08;IoT&#xff09;的海洋中&#xff0c;数据像水流…

mysql的约束和表关系

根据查询的结果&#xff0c;复制出一个新表 create table newTable AS select * from oldTable; create table newPeople AS select * from day2_test.people; 约束 引入&#xff1a;如果某一列如id列&#xff0c;有重复的数据&#xff0c;无法准确定位&#xff0c;有的列有空…

Jenkins CI/CD 持续集成专题一 Jenkins的安装和配置

一 jenkins 官方教程 安装Jenkins 二 安装 2.1 安装方式一 通过安装包的package方式安装 第一步下载链接&#xff1a; Download the latest package 第二步操作方式&#xff1a;打开包并按照说明操作即可安装 2.2 安装方式二 brew安装 第一 安装最新版本jenkins brew in…