首页 > 系统相关 >整数和浮点数在内存中储存

整数和浮点数在内存中储存

时间:2024-09-11 21:51:56浏览次数:11  
标签:存储 字节 int 浮点数 储存 内存 pFloat

1.整数的储存

在生活中,我们通常运用十进制计数。而在计算机数据在内存中是以二进制的方式存储。

1).整数的存储方式

整数的2进制表示方法有三种,即原码、反码和补码 

有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用 1 表示“负”,最高位的⼀位是被当做符号位,剩余的都是数值位。

而对于整形来说:数据存放内存中其实存放的是补码。要想知道,整形在内存中的表现形式,就需要了解原码、反码和补码三者之间的转换关系。

正整数的原、反、补码都相同。

负整数的三种表表示法各不相同:

原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。

反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。

补码:反码+1就得到补码

如 int a = 5;

对于已初始化变量 a ,它的值为5,5为正数;而 int 类型的大小是四个字节,即 32 位所以它内存中的存储形式为:00000000 00000000 00000000 00000101。

又如 int b = - 4;

b等于 - 4 ,为负数;- 4转化二进制形式,得到它的原码:

                    10000000 00000000 00000000 00000100

 反码为:     11111111  11111111  11111111  11111011

补码为:       11111111  11111111  11111111  11111100 即为 -4 在内存中的存储形式

同理,负数的补码想要得到原码,减一取反即可。

2).大小端字节序

1.什么是大小端字节

首先看一个例子:

在vs2022上对这段代码进行调试,我们可以看到,我们可以看到在a中的 0x11223344 (十六进制)这个数字是按照字节为单位,倒着存储的。

对于为什么这样存储,这就涉及到大小端字存储模式:

大端(存储)模式: 是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。

小端(存储)模式: 是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。 上述概念需要记住,方便分辨大小端。

 从左到右为低地址初到高地址处  即 :   低地址初  ------->  高地址。

 如上述为小端模式,最高位字节内容的 44 存储在最右边(高地址),最低位字节的 11 最左边(低地址)。

2.大小端字节序判断

我们也可以写一段代码来判断所用编译器使用的是哪种存储模式。

#include <stdio.h>
int main()
{
	int a = 1;
	int ret = *((char*)&a); //拿出a的第一个字节
	if (a == 1)
		printf("小端");   // 01 00 00 00
	else
		printf("大端");   // 00 00 00 01
	return 0;
}

浮点数的存储

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

在编译器中运行这段代码得到的是这样的结果,要了解其原因,首先的了解浮点数在计算机内部的表示方法。

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

如:5.5 写成二进制形式为 101.1。

改写为上述形式即:(-1)^0 * 1.011 * 2^2      S:0 ; M=1.011 ; E=2。

IEEE754规定:

1.对于32位的浮点数,最高的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M

2.对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

2.浮点数的存储过程

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

1. 对于 M有 1≤M<2,即M可写为 1.xxxx。IEEE 754规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后面的 xxxx部分。

比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。 

以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保 存24位有效数字。

2. E为⼀个无符号整数(unsigned int),如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。

但是,我 们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上 ⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。

比如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

3.浮点数的拿出过程

1.E不全为0或不全为1这时:

浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效 数字M前加上第⼀位的1。

如5.5:(-1)^0 * 1.011 * 2^2      S:0 ; M=1.011 ; E=2。

2+127=129  即10000001;M去1 为 011。

按照前面的存储方法 它的二进制表示为:0 10000001 01100000000000000000000

2. E全为0

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

3.E全为1

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

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

第一个输出值:以int类型初始化的变量n大小为 9 ,在以十进制整形格式输出 打印结果为 9。

第二个输出值:9 以整形存储到内存中的二进制形式为 00000000 00000000 0000000 00001001

以浮点数存储的眼光来看 即为(-1)^0 * 1.0000000 0000000 00001001* 2^-126 这个数无限接近为0,以 %f 的位数打印出的结果为0。

第三个输出值:  9以浮点数的存储形式为 (-1)^0 * 1.001*2^3   即  S = 0; E = 3; M = 1.001

即0 10000010  00100000000000000000000 以整形打印这个二进制数,由计算器可知,结果符合输出值。

第四个输出值:此时n的类型为float,以浮点数的格式打印,结果为带小数位的整数值。

标签:存储,字节,int,浮点数,储存,内存,pFloat
From: https://blog.csdn.net/2402_86767488/article/details/142147629

相关文章

  • 内存延迟对Zen5游戏性能影响有多大!为何首发评测我们会用技嘉X670E AORUS XTREME主板
    一、前言:为什么我们会一直使用技嘉X670E主板做锐龙处理器首发评测很多同学一直好奇,为什么我们在各种锐龙平台的评测中都会优先使用技嘉X670主板?也有同学很疑惑,为什么海外媒体的游戏性能测试,锐龙79700X连i7-14700K都打不过,而在我们这里却与i9-14900K旗鼓相当?主要原因是Zen5架构......
  • 内存屏障简介
    内存屏障编译乱序异步场景中,经常使用多线程一起处理任务并且通过一个共享变量进行状态的共享,如下,function2在请求data数据时通过status判断数据是否就绪,function1准备数据完成后修改status。boolstatus=false;chardata[50]="Hello";voidfunction1(){strcp......
  • C# WebSocket Fleck 内存泄漏
    最近在维护公司旧项目,内存泄漏严重,找了行业内大佬帮忙分析Dump文件(windbg我不擅长),大佬指出问题在于Fleck,这里记录一下。整理一下问题:1.大佬指出System.Threading.Tasks.ContinuationTaskFromTask和System.ObjectDisposedException有71完个对象。2.System.ObjectDisposedE......
  • C语言的数据在内存中的存储
    在之前的二进制及其相关操作符与结构体内存对齐两篇文章中,我们已经对二进制数,原码反码补码进行了浅层的了解,并且也知道了高低地址以及高低字节的区别,那么既然知道了这些基础知识,就让我们借助这一层台阶,继续往更高的地方(数据在内存中的存储)大迈步吧~一、二进制数日常生活中......
  • 项目-高并发内存池
    本篇文章,和大家分享和一些和项目相关的知识。本次的内容主要是模拟实现一个高并发内存池。项目介绍我们这个项目的原型是google的tcmalloc,tcmalloc的全称是Thread-CachingMalloc。我们之前使用的malloc,free,本身就是一个内存池,只不过google的这个在多线程方面更高效。那我们是不......
  • C语言:数据在内存中的存储
    一.整数在内存中的存储首先,在讲解操作符的时候,我们就已经知道了,对于整形来说:数据存放内存中其实存放的是补码。并且我们也知道补码是整数的2进制表示方法之一。整数的2进制表示方法有三种,即原码、反码和补码有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是用......
  • 如何在 Linux 系统中查看 CPU 核数和内存大小
     在日常运维和开发中,了解服务器或虚拟机的硬件配置是非常重要的一环。无论是进行性能调优,还是资源分配,了解CPU的核数和内存大小可以帮助我们更好地规划应用的运行环境。本篇博客将介绍如何在Linux系统中查看CPU核数和内存大小。一、查看CPU核数在Linux中,查看CPU......
  • C语言中的磁盘映射与共享内存详解
    文章目录C语言中的磁盘映射与共享内存1.磁盘映射(MemoryMapping)1.1磁盘映射的深入概念1.2`mmap`函数的详细参数解析1.3磁盘映射的高级应用场景1.3.1大文件处理1.3.2内存共享1.3.3文件与内存同步1.3.4内存映射数据库1.4完整的磁盘映射代码示例1.5注意事项2.......
  • 数据在内存中的存储
    今天学习数据在内存中的存储目录1.整数在内存中的存储基础概念注意对于整形来说:数据存放内存中其实存放的是补码。2.大小端字节序和字节序判断2.1大小端概念**大端(存储)模式:****小端(存储)模式:**2.2为什么有大小端例3.浮点数在内存中的存储3.1浮点数的存储举例来说:IE......
  • 动态内存管理
    C/C++malloc-free底层原理-动态内存管理关于动态内存管理这块在面试中被考察频率非常高,切入的点也很多,有从操作系统虚拟内存问起的,也有从malloc、new等开始问起的。但是无外乎就是两块内容:虚拟内存机制:物理和虚拟地址空间、TLB页表、内存映射动态内存管理:内存管理、分配......