整数与浮点数在内存中的存储

整数与浮点数在内存中的存储

  • 一,大小端存储
  • 二,整数在内存中的存储
  • 三,浮点数在内存中的存储
    • 3.1浮点数的存储规则
    • 3.2浮点数的存储过程
      • 3.2.1有效数字M
      • 3.2.2指数E
      • 3.2.3浮点数存储的特殊情况
      • 4,例题讲解

在C语言的编程中,我们常常创建整型与浮点型的变量,这里我们介绍内存中它们是如何进行转换和存储的。 文章中展示的例子是在32位系统下使用VS2022进行操作的结果,不同软件可能会有大小端的区别。
首先介绍一下大小端存储及区别

一,大小端存储

大小端存储指的是对于多字节数据的表示方式,即字节序。

大端存储(Big Endian):高位字节存储在内存的低地址处,低位字节存储在内存的高地址处;
小端存储(Little Endian):低位字节存储在内存的低地址处,高位字节存储在内存的高地址处
例如:

int a=0x11223344;我们以16进制的方式创建一个变量a,在大端存储中,a的存储方式应该为0x11 22 33 44(从左到右地址逐渐递递增)在小端存储中,a的存储方式应该为0x44 33 22 11(从左到右地址逐渐递递增)

在实际应用中,不同的体系结构和处理器可能采用不同的字节序。但无论是大端存储还是小端存储,在将变量从内存中拿出使用时都会将其还原成正确的形式。

二,整数在内存中的存储

在现代的计算机中主要采用的数字集成电路完成,数字电路通过高低电平只能表示0和1,所以就出现了,计算机只会识别0和1。无论是存储还是计算,计算机均采用二进制体系完成。
在C语言中不同数据类型的大小不一样,如int类型每个占4个字节,而每个字节又等于8个比特位。
sizeof(int)=1byte=8bit每个比特位存储的便是0或1。
一个int类型共有32个比特位,每个比特位只能是0或1,而我们又知道,整型包括有符号整型和无符号整型,无符号整型只有正整数,范围为0~232-1,而有符号整型既有正整数又有负整数,范围为 -231 ~231-1
那为什么会存在正负数之分?操作系统又是如何分辨正负数的?
这就需要了解关于原码反码补码的知识了。

十进制数在计算机中通常不是直接储存的,而是先转化位二进制数在进行存储。而为了区分正负数,计算机对有符号整数采用了不同的编码储存方式,也就是源码,反码,补码。

我们分开讨论正负整数的存储:
正整数:正整数的源码=反码=补码
负整数的三种表示方法各不相同。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。

int a=5;
a的源码=反码=补码为:0000 0000 0000 0000 0000 0000 0000 0101
int b=-5;
b的源码为:1000 0000 0000 0000 0000 0000 0000 0101反码为:1111 1111 1111 1111 1111 1111 1111 1010补码为:1111 1111 1111 1111 1111 1111 1111 1011

而计算机之所以会有三种储存整形的方式的原因都是因为计算的难易,

源码的一个缺点是存在两种不同的表示方式来表示0(0000 和 1000),这可能导致一些不必要的复杂性。
反码的一个优点是消除了0的两种表示,但缺点是进行加减运算时相对复杂。
补码是最常用的表示法,特别是在现代计算机中。补码的一个主要优点是它使得加法运算更加简单,因为对于任何整数x,都有 x + (-x) = 0,这在补码表示下总是成立。另一个优点是只有一个0的表示(0000),这使得处理更加简单。使用补码,可以将符号位和数值域统⼀处理

对于整形来说:数据存放内存中其实存放的是补码。

三,浮点数在内存中的存储

3.1浮点数的存储规则

C语言中的浮点数类型包括: float、double、long double 类型。
计算机读取浮点型和整型的方式是不一样的,我们先来看一段代码:

#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("num的值为:%d\n",n);printf("*pFloat的值为:%f\n",*pFloat);return 0;
}

结果为:
在这里插入图片描述
而造成这样的原因,就是因为计算机读取存储的浮点数和整型的方式是不一样的。

根据国际标准IEEE(电气和电子⼯程协会)754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
V = (−1) S ∗ M ∗ 2E
• (−1)S 表示符号位,当S=0,V为正数;当S=1,V为负数
• M表示有效数字,M是大于等于1,小于2的
• 2E 表示指数位

了解上面的知识后,我们还需知道,在二进制中小数点后的数字是如何划算的,
例如:
5.5,写成二进制表示为101.1,在转换成科学计数法为1.01×103
小数点前就是正常的二进制转十进制从右往左的单位依次为20,21,22……,小数点后的第一个1表示2-1,然后往后若存在数,依次为2-2,2-3……,
所以二进制101.1划算为十进制的算式就为:
**1×22+0×21+1×20+1×2-1=5.5,
了解之后,再结合上面的国际标准中计算机存储浮点数的方式来介绍计算机中的浮点数存储。
例:
⼗进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2
(5.5相当于1.011×23)
那么,按照上⾯V的格式,可以得出S=0,M=1.01,E=2。
⼗进制的-5.0,写成⼆进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。
当然,32位机器和64位机器在存储浮点数上也有细微的差别。

IEEE 754规定:
对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M.
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。

32位浮点数(float):
在这里插入图片描述
64位浮点数(double):
在这里插入图片描述
所以,浮点数的存储其实就是存储S,E,M相关的值。

3.2浮点数的存储过程

IEEE 754 对有效数字M和指数E,还有⼀些特别规定。

3.2.1有效数字M

前⾯说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表示小数部分。
IEEE 754规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后⾯的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去。
例如:
5.5为101.1==>1.011×22
0.5为0.1==>1.0×2-1
这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保存24位有效数字。

3.2.2指数E

首先,我们要了解,指数E为一个无符号整数(unsigned int)。所以当存储的为32位浮点数时,E的取值范围为0~255;存储64位浮点数时,E的范围为0 ~2047。
但是,我们知道,科学计数法中是存在负数的。
所以IEEE 754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,210的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
综合来说,这当中的E的存储存在三种情况:
一,E不全为0或不全为1
这时,E的存储就为指数加上中间值,例如:存储32位浮点数0.5
0.5的二进制数为0.1,按照IEEE 754的规则转换,为正数S=0,有效数字M要大于等于1并且小于2,所以小数点右移一位,M=1.0,E=-1,
0.5= (−1) 0 ∗ 1.0 ∗ 2-1
存储时,为正数,符号位(S)为0,阶码(E)-1+127(中间值)=126,转化为二进制01111110。将二进制存入E的八位中。尾数(M)1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其⼆进制表示形式为:

0(S) 01111110(E) 00000000000000000000000(M)

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

0 00000000 001000000000000000000000

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

0 11111111 00010000000000000000000+

3.2.3浮点数存储的特殊情况

在浮点数存储的时候,因为小数点后的数依次表示2-x逐渐递减,所以有些数是不能精确存储的,例如:

#include <stdio.h>
int main()
{float a = 0.4554f;printf("%.10f ", a);return 0;
}

在这里插入图片描述
出现这种情况,计算机会根据两数之间的差的绝对值小于一个很小的范围来存储一个十分接近的数,双精度比单精度浮点数会更加接近实际的值。

4,例题讲解

了解完浮点数的存储规则后我们再来看下开始的例题:

#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("num的值为:%d\n",n);printf("*pFloat的值为:%f\n",*pFloat);
return 0;
}

首先,将整型n转化为二进制补码存入内存:
因为正整数的原码,反码,补码相等,所以n的补码就为:

00000000 00000000 00000000 00001001

当我们以整型形式打印时,就是正常打印,
但是,当我们以32位浮点数的形式打印时,计算机就会将补码以浮点数的形式读取

0(S) 00000000(E)  00000000000000000001001(M)

符号位为0,表示为正数,又因为E全为0,按照上面介绍的情况,此时的指数为1-127,非常小,无限接近于0,也就是小数点后有效数字出现的位数很小,所以我们以浮点数形式打印时,显示的位数有限,所以近似取0;
————————————————————
我们再来看下以浮点数形式存入9.0;
此时浮点数按照规定的规则存入内存(9.0=>1001.0=>1.001×23),二进制码为:

0(S) 10000010(E) 00100000000000000000000(M)

当我们以浮点数形式打印时,就是正常打印,
但是,当我们以整型的形式打印时,计算机就会将二进制码以整型的形式读取,

01000001 00010000 00000000 00000000

按照整型的形式读取,该数就为一个很大的正数,为:
230+224+220,我们使用计算器计算一下:
在这里插入图片描述

,所以
在这里插入图片描述
这就是打印的结果。

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

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

相关文章

分布式系统架构中的相关概念

1.1、衡量网站的性能指标 响应时间&#xff1a;指执行一个请求从开始到最后收到响应数据所花费的总体时间。并发数&#xff1a;指系统同时能处理的请求数量。 并发连接数&#xff1a;指的是客户端向服务器发起请求&#xff0c;并建立了TCP连接。每秒钟服务器连接的总TCP数量请…

Python--Django--说明

Django 是基于python 的 Web 开发框架. &nsbp;   Web开发指的是开发基于B/S 架构, 通过前后端的配合, 将后台服务器上的数据在浏览器上展现给前台用户的应用. &nsbp;   在早期, 没有Web框架的时候, 使用 Python CGI 脚本显示数据库中的数据. Web框架致力于解决一些…

c++宏有什么离谱操作?

Boost.Preprocessor确实是一个非常强大而复杂的C宏库&#xff0c;专门用于元编程&#xff0c;即在编译时进行代码生成和变换。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程不妨点个关注&#xff0c;给个评论222&…

面试总结------2024/04/04

1.面试官提问&#xff1a;你说你在项目中使用springsecurity jwt 实现了登录功能&#xff0c;能简单讲一下怎么实现的吗&#xff1f; 2.使用RabbitMQ实现订单超时取消功能 订单状态定义 首先&#xff0c;我们需要定义订单的不同状态。在这个示例中&#xff0c;我们可以定义以下…

实验一 Windows 2008虚拟机安装、安装VM Tools、快照和链接克隆、添加硬盘修改格式为GPT

一、安装vmware workstation软件 VMware workstation的安装介质&#xff0c;获取路径&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1AUAw_--yjZAUPbsR7StOJQ 提取码&#xff1a;umz1 所在目录&#xff1a;\vmware\VMware workstation 15.1.0 1.找到百度网盘中vmwa…

Pandas Dataframe合并连接Join和merge 参数讲解

文章目录 函数与参数分析otheronhowlsuffix, rsuffix, suffixesleft_index, right_index 函数与参数分析 在pandas中主要有两个函数可以完成table之间的join Join的函数如下&#xff1a; DataFrame.join(other, onNone, how‘left’, lsuffix‘’, rsuffix‘’, sortFalse, v…

YOLOv8 UI界面设计+热力图显示

进入可视化设计界面&#xff0c;设计UI pyside6-designer 设计好UI保存&#xff0c;然后通过以下命令将ui文件保存为py pyside6-uic myui.ui > myui.py 通过以下命令将资源文件qrc保存为py pyside6-rcc my_rc.qrc > my_rc.py 写主窗口函数实现功能... 项目基于yol…

基于Spring Boot的职称评审管理系统

基于Spring Boot的职称评审管理系统 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 部分系统展示 前台首页界面 用户注册登录界面 管理员登录界面 个人中心界面…

Driver not loaded之记录Qt访问MySql的解决经历

对于这个问题的本质原因&#xff0c;我也搞不明白&#xff0c;所以记录的方法不一定对所有人行之有效。我的目的很简单&#xff0c;就是把数据库用起来&#xff0c;经过查找网上资料&#xff0c;最终把数据库跑起来了。因此记录如下&#xff1a; 1&#xff0c;出现这个问题是缺…

【Go】十六、文件操作

文章目录 1、打开和关闭文件2、IO3、一次性读文件4、带缓冲区的读文件5、写入文件6、文件复制 1、打开和关闭文件 package main import("fmt""os" ) func main(){//打开文件&#xff1a;file,err : os.Open("d:/Test.txt");if err ! nil {//出错…

【医学影像数据处理】nii 数据格式文件操作汇总

大部分医学领域数据存储的都是dicom格式&#xff0c;但是对于CT等一类的序号图像&#xff0c;就需要多个dicom文件独立存储&#xff0c;最终构成一个序列series&#xff0c;这样存储就太过于复杂了。 nifti&#xff08;Neuroimaging Informatics Technology Initiative&#x…

GT收发器64B66B协议(2)自定义PHY设计

文章目录 前言一、设计框图二、GT_module三、PHY_module3.1、PHY_tx模块3.2、PHY_rx_bitsync模块3.3、PHY_rx模块 四、上板测试 前言 有了对64B66B协议的认识以及我们之前设计8B10B自定义PHY的经验&#xff0c;本文开始对64B66B自定义PHY的设计 一、设计框图 二、GT_module …

蓝桥杯单片机速成8-NE555频率测量

一、原理图 NOTE&#xff1a;使用NE555测量频率之前&#xff0c;需要将J3-15(SIGNAL)与J3-16(P34短接) 在使用矩阵键盘的时候也记得把跳冒拔下&#xff0c;因为有公共引脚P34 又是因为他的输出引脚是P34&#xff0c;所以只能用定时器0来作为计数器进行频率测量了 二、代码实现 …

CSS设置网页背景

目录 概述&#xff1a; 1.background-color: 2.background-image&#xff1a; 3.background-repeat&#xff1a; 4.background-position&#xff1a; 5.background-attachment&#xff1a; 6.background-size&#xff1a; 7.background-origin&#xff1a; 8.background-…

Linux初学(十四)LampLnmp

一、简介 LAMP和LNMP是两种常见的web服务器组合。具体如下&#xff1a; LAMP&#xff1a;LAMP代表的是Linux&#xff08;操作系统&#xff09; Apache&#xff08;HTTP服务器&#xff09; MySQL&#xff08;数据库&#xff09; PHP&#xff08;编程语言&#xff09;。这个组合被…

C++利用键值对计算某一个数对应的最值及其索引位置

目录 一、算法概述二、代码实现1、计算最值2、计算最值及其索引 三、结果展示 本文由CSDN点云侠原创&#xff0c;原文链接。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫与GPT。 一、算法概述 类似下图所示&#xff0c;计算第一列中1或2对应的最…

线段树练习

1.单点修改区间查询 P3374 【模板】树状数组 1 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某一个数加上 x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 n,m&#xff0c;分别表示该数列数字的个数和操作的总个…

ChatGPT 与 OpenAI 的现代生成式 AI(下)

原文&#xff1a;Modern Generative AI with ChatGPT and OpenAI Models 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 七、通过 ChatGPT 掌握营销技巧 在本章中&#xff0c;我们将重点介绍营销人员如何利用 ChatGPT&#xff0c;在这一领域中查看 ChatGPT 的主要用例…

Delphi编写的图片查看器

UNIT Unit17;INTERFACEUSESWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,Vcl.StdCtrls, Vcl.ExtDlgs, Vcl.ExtCtrls, Vcl.Imaging.jpeg; //注意&#xff1a;要加入jpej 否侧浏览图…

ids工业相机与电控位移台同步控制及数据采集

通过VS2017和OpenCV,实现ids工业相机与电控位移台同步控制及数据采集 目录项目环境配置代码流程及思路项目架构项目开发运行效果开发关键ids相机配置位移台环境配置相机头文件相机参数设置保存图像函数设置电控位移台头文件电控位移台设置参数最后就是通过main函数进行调用和控…