数据在内存中的存储

整数在内存中的存储

我们都知道,数据在内存中是以二进制的方式进行存储的,整数的二进制有原码,反码和补码三种,而真正在内存中存放的就是补码。

我们先简单了解一下这三种表示方式:

正整数的原、反、补码都相同。
负整数的三种表⽰⽅法各不相同。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
 

为了方便,我们简单用8个比特位来解释一下,我们主要说一下负数

-6 的二进制表示:

原码:10000110

反码:11111001

补码:11111010

前面的1表示符号位,正数的话就是0

所以对于无符号整数来说,没有符号位,所有比特位全部表示数值

对于以下代码,可以思考以下运行结果

int main() {
	unsigned int i;
	for (i = 9; i >= 0; i--) {
		printf("%u ", i);
	}
	return 0;
}

结果是程序会陷入死循环,因为是无符号的整型,当 i 减到 0 之后会变成一个特别大的数字,一直都不会小于0,就是下图中的效果

大小端和字节序的判断

什么是大小端呢?

我们通过一个例子来说明

可以看出,为什么在内存中n的存储是倒着的

这就是我们要说的大小端的问题了

  • 大端字节序:在这种模式下,数据的高字节保存在低地址,低字节保存在高地址。也就是说,最高有效字节排在最前面,最低有效字节排在最后面。例如,十六进制数0x12345678,在内存中的存储顺序是:12 34 56 78。
  • 小端字节序:与小端相反,数据的低字节保存在低地址,高字节保存在高地址。即最低有效字节排在最前面,最高有效字节排在最后面。以十六进制数0x12345678为例,其在内存中的存储顺序是:78 56 34 12。

大端的优势在于第一个字节就是高位,容易判断数据的正负性;而小端的优势在于最后一个字节是高位,可以依次取出相应的字节进行运算,并且最终会把符号位刷新,运算起来更高效。

我们也可以写一个程序来判断当前机器是大端存储还是小端存储:

#include <stdio.h>
int check_sys()
{
	int i = 1;
	return (*(char *)&i);
}
int main()
{
	int ret = check_sys();
	if(ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

浮点数在内存中的存储

存储过程

例如5.5的二进制表示为101.1,可以转化为(-1)^0 * 1.011*2^2,此时S=0,M = 1.011,E=2

float 类型的小数点后面可以存23个比特位,double类型 小数点后面可以村 52 个比特位,

M的存储

在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的小数部分。例如,如果要存储1.01这样的数,实际上只需要保存01,而在读取时,再将第一位的1加上去。这样做的目的是为了节省1位有效数字。在32位浮点数中,将尾数的第一位默认为1后,剩下的位数就可以用来表示更多的有效数字。

指数E的存储

  • 在存储过程中,指数需要经过一个偏移处理。这是因为在计算机中,指数可以是正数或负数,而直接存储负数在计算机中是不方便的。因此,IEEE 754标准定义了一个偏移量(对于单精度浮点数是127,对于双精度浮点数是1023)。实际存储的指数值是原指数值加上这个偏移量。
  • 指数部分在内存中占据一定的位数,对于单精度浮点数通常是8位,双精度浮点数则是11位。这些位数用于精确地表示指数的范围。

我们来用一个例子解释以下:

对于5.5来说,二进制为101.1,也就是1.011*2^2,又可以转化为 (-1)^0*1.011*2^2

此时,S=0,M=1.011,E=2

但是我们在内存中存要加上偏移量,也就是2+127 = 129

内存中就是 0 10000001 01100000000000000000000

换成16进制就是 40 B0 00 00

接下来我们验证一下

 明显,f的内存和我们计算的一样,只不过由于小端存储是 00 00 b0 40

取出过程

取出过程正好是和存储相反的,也就是指数E的值减去127(1023),得到真实值,再将有效数字前面加上第一位的1,因为之前的1是没有存入的。

另外还有两种特殊情况:

E全为0,说明E是-127这样的数字,也就是1的-127次方,一个特别接近0的数字,表示+-0以及接近0的很小的数字

E全为1,同理,此时表示的是一个非常大的数字。

那么数据在内存中的基本存储原理就分享到这里了,有机会再补充。

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值