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

本文探讨了整数(包括正负整数和不同类型的存储如原码、反码和补码)在内存中的存储方式,以及大端存储和小端存储的区别。同时,介绍了浮点数(如32位和64位float/double)的存储结构和规则。
摘要由CSDN通过智能技术生成

1.整数在内存中的存储

(1).原码,反码,补码

我们都知道,一个整数类型的数据,不管是正数还是负数,都是可以转换成二进制类型的数据。而一个整数类型是4个字节,一个字节等于8个比特位,因此,一个整形数据就等于32个比特位。这就意味着在转换成二进制的时候需要小心,避免把0/1写错。

而整数在内存中的存储,则是以二进制的形式来存储的。二进制位的最高位是符号位。对于正整数来说,十进制转换成二进制形式的原码,反码和补码都是一样的,在内存中,存储的是补码;对于负整数来说,十进制转换成二进制形式的原码,反码和补码却都是不一样的。他们之间可以相互转换。反码:在原码的基础上,除了最高位不变,其他的位按位取反。补码:在反码的基础上,最低为+1。而对于补码转换成原码,也是进行相同的操作。

(2).大端存储和小端存储

大端存储和小端存储是两种不同的数据存储方式,对于不同的机器,其存储的方式也有所不同。那么什么是大端存储呢?

大端存储模式:将数据的低位字节存储到高位地址中,高位字节存储到低位地址中

小端存储模式:将数据的低位字节存储到低位地址中,高位字节存储到高位地址中

(3).下面来看几个代码       

第一个

#include <stdio.h>
int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("%d %d %d", a, b, c);
	return 0;
}

这个代码打印的结果是-1,-1,255。这就让我一开始感觉到非常奇怪,这是为什么呢?

首先来分析一下下代码

我们可以发现,这三个变量的原码反码补码都是一样的,那为什么输出的结果是不一样的?我们继续往下看看~

首先看char a,一个char类型的数据只能存放一个字节大小的数据,但在这里放进去了四个字节的数据,而整形数据在内存中又是按补码存放的。因此,将会发生整型截断,按低位取值,只取低位的那个字节 ---->11111111

而signed char,unsigned char也是一样的。

在使用%d输出时,%d的作用以十进制的形式打印有符号的整形。因此在打印的时候由于他们只有一个字节,因此要进行整型提升。而在VS编译器中,char类型被默认成与signed char类型相同,都是有符号类型的数据,因此对于有符号类型的数据发生整型提升时,看符号位,符号位是几,就往前面补几,补到32位为止。

而对于无符号类型数据,他的每一个位都是有效位,是没有符号位的,因此,在无符号类型发生整型提升时,由于他没有符号位,因此在提升的时候需要往前面补0。

因此就会输出-1,-1,255

第二个

输出的结果是一个非常大的数,与第一个类似,我就不多说了。

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

对于浮点数在内存中的存储,我们首先来看一个东西。

也就是说,如果想存储一个浮点数类型的数据,首先要将其化成二进制的形式,然后再将二进制的形式写成如上图的那种形式。

而在浮点数的存储当中,是以S E M的顺序来存储的。

对于一个32位(float)的浮点数类型,最高一位存储符号位S,接着8位存储指数E,最后剩下的23位存储有效数字M

而对于一个64位(double)的浮点数类型,最高一位存储符号位S,接着11位存储指数E,最后剩下52位存储有效数字M

存储的大概方式我们知道了,那存储规则呢?

以32位的浮点数为例,首先把S存放到第一个比特位,如果是正数就存0,负数就存1;接着把E+127所得到的数字转换成二进制位存入11个比特位中;最后把M存进去,但一般来说,M都是写成1.xxxxxxx的形式的,因此在存储这个数据的时候,我们可以把1给省略掉,只存放小数点后面的数字,如果存完了小数点后的数字还剩余比特位没存的话,就存0上去就可以了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值