数据在内存中的储存

本文详细解释了整数(包括原码、补码和反码)在内存中的存储机制,以及大小端字节顺序的概念。同时介绍了浮点数(如IEEE754标准)在内存中的存储结构,包括如何表示、存储和提取过程,通过实例解析了代码中的内存行为。
摘要由CSDN通过智能技术生成

1.整数在内存中的储存

      整数在内存中是以二进制的形式进行储存,每个整数都有对应的二进制表示,并且都有:原码补码反码三个概念。对于正整数来说,这“三码”是一模一样的,而对负整数来说就有不同的表示。

      在了解这“三码”之前我们需要知道,整型是四个字节的大小,有4*8=32个比特位,最高位是符号位,例如:1000 0000 0000 0000 0101,这串二进制数字的红色1,就是这串二进制的符号位,表示这个数是负数,而其他都是数值位。反之,如果最高位是0,则说明这个数是没有符号的整数。那为什么无符号整数的“三码”相同呢?接下来就来介绍一下这三个码。

1.1 什么是原码、补码、反码

       原码:原码就是我们所看到的二进制,比如说5的二进制表示是0101,当然,前面还有很多很多0,我们这里就不写了。这便是正数的二进制表示。,如果是-5呢,那只需要在最高位的0变成1就可以了(是第32位的0哦~)。

       补码:补码就是由原码变来的,将原码进行取反,得到的就是补码。还是5——0101,取反之后就是1010.取反的时候要注意,符号位是不能改变的。

       反码:反码就是反码+1,也就是原码取反后+1.在计算机里,整型就是以其反码的形式储存的。反码要得到原码也只要进行取反后+1即可。

1.2 为什么计算机里用反码储存数据 

            为什么是用反码的形式储存呢?

                   因为用反码储存可以更方便数据的直接运算;CPU里只有加法器,说明计算机只能进行加法运算。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
 

2.大小端字节储存顺序

   我们来看一个代码的调试:

这里我们可以看到整型a是倒着储存的。

2.1 什么是大小端

 首先我们要知道,什么是大小端储存?

     大端储存模式:将数据的低位储存到高地址处,数据的高位储存在低地址处。

     小端储存模式:将数据的高位储存在高地址处,数据的低位储存在低地址处。

 在数据超过一个字节的时候就会有大小端储存。那为什么会有大小端储存呢?

2.2 为什么会有大小端

     因为数据在内存中都是以二进制的形式储存,一个字节就有8个比特位,但是我们知道不仅有char类型的数据,还有short、int、long等类型,它们的大小都超过了1个字节,有非常多的比特位。这时候就需要约定好,这些比特位应该是按照大端还是小端储存,这样数据才不会杂乱无章。一会是小端储存,一会是大端储存,这样显然不行。

3.浮点数在内存中的储存 

我们常见的浮点数有:3.14159,1E10等,浮点数类型的成员有:float、double、long double。浮点数范围的定义在头文件:float.h里

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

 这段代码的结果:

明明n在内存中储存的就是9,那为什么从不同的浮点类型的角度,输出的结果就是不一样呢。接下来我们就要来了解浮点数在内存中是怎么样的储存形式。

3.2 浮点数在内存的储存

根据国际标准IEEE(电⽓和电⼦⼯程协会)754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:

V:是浮点数的值

S:决定了浮点数的正负,如果为0,则为正,为1就为负

M:表示有效位,但是M是大于等于1,小于2的

E:这是2的E次幂

例:5.0的二进制表示是101.0,写成上面的形式就是1.01*2^2.

那么,按照上⾯V的格式,可以得出S=0,M=1.01,E=2。
⼗进制的-5.0,写成⼆进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。

可能看着有点懵,将这个表示方法类比科学计数法,科学计数法是表示十进制的数,例子里面是二进制数,2的E次幂就相当于科学计数法10的E次幂。

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

3.2.1 浮点数存储的过程

   我们上面说了M的取值是[1,2)的,那么一个浮点数1.xxxxxx里的个位1就可以省略,这样储存的时候就可以多一位去储存小数部分,32位的浮点数的M就有24位,64位就有53位。

   E的储存:E是一个无符号整型,我们知道在科学计数法里面,10的幂是可以为负的,这里2的幂也是可以为负的,但是我们又不能在表示负数,所以我们对于指数E的储存都要加上一个中间值,8个比特位的值是0~255,它的中间值就是127,比如2^10的E是10,在计算机里面的储存就是10+127=137,写成二进制就是10001001.

3.2.2 浮点数取出的过程

取出时,E有三种情况:

E不全为1或者0:这时只需要将储存好的E减去127或者1023(64位的中间数)还原即可。

E全为0:这时候就是用来表示非常小的小数。这时E的值就是它的真实值,而M也不用加上1,而是直接还原为0.xxxxxxx的小数。

E全为1:这时表示正负无穷大。

3.2.3 回到引例 

 看到输出全为0:9的二进制是1001,当从浮点数的角度去输出时,先把这段序列变成浮点数的储存形式,0000 0000 0000 0000 0000 0000 0000 1001,从浮点数的角度去解读时,E全为0,就说明这是一个无限趋近于0的数字,表示为:

V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146),V是一个非常非常小的数字,用十进制的浮点数表示时就为0.0000000.

 再看到输出一串很大的数字:n先是被改成了9.0,变成了一个浮点型,那么V=(-1)^0*1.001*2^3

S=0,E=3,在内存里就是E=3+127=130,M=001,个位的1被拿掉了,后面的位都补0.

所以换成二进制就是0 10000010 001 0000 0000 0000 0000 0000。这个就是9.0在内存的储存二进制序列,也就是反码(上面提到的),然后再从整数的角度去输出(输出原码),答案就是原码的十进制形式1091567616。

   希望该文章对你有所帮助,感谢观看!

  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值