数据的存储

目录

1、大端字节序与小端字节序

1.1 字节序的产生

1.2 理解大小端字节序

1.2.1 举例说明

1.2.2 用程序判断大小端存储

2、整型在内存中的存储

2.1 原码、反码与补码

2.2 反码和补码原理

2.3 整型类型与范围

3、浮点型在内存中的存储

3.1 IEEE754标准

3.1.1 浮点型 内存存储

END 


1、大端字节序与小端字节序

1.1 字节序的产生

      首先需明确的是数据存储单位为字节,当数据以多字节形式进行存储时则需要考虑存储顺序,单字节存储无需考虑。

1.2 理解大小端字节序

      大端字节序:数据低位存放高地址,数据高位存放低地址。

      小端字节序:数据高位存放高地址,数据低位存放低地址。

1.2.1 举例说明

      设有整型变量存放值0x11223344,大小端存储模式如下:

       显然在VS平台下,数据为小端存储。

1.2.2 用程序判断大小端存储

代码思路:判断低地址起始的第一个字节的内容就可以判断大小端了。同样以0x11223344为例,若第一个字节为0x44则为小端。由于传参类型为整型,需要取出一个字节则可以使用char类型的强制类型转换。代码如下:

#include <stdio.h>
void Judge_Storage(int num)
{
	char* ptr = (char*)&num;
	if (0x44 == *ptr)
	{
		printf("小端");
	}
	else
	{
		printf("大端");
	}
}

int main()
{
	int A = 0x11223344;
	Judge_Storage(A);
	return 0;
}

2、整型在内存中的存储

2.1 原码、反码与补码

原码:有符号整数的二进制形式,第一位表示符号位,其余表示数值。

例如:

1的原码在32位机器上的表示为:

 -1的原码在32位机器上的表示为:

反码:正数反码与原码相同;负数反码符号位不变,其它位按位取反。

例如:

1的反码在32位机器上的表示为:

 -1的原码在32位机器上的表示为:

补码:正数补码与原码相同;负数补码为反码加1.

例如:

1的补码在32位机器上的表示为:

 -1的补码在32位机器上的表示为:

2.2 反码和补码原理

计算机中的任何数据类型都有上限和下限,譬如signed char 类型取值是-2^{7}\sim 2^{7}-1 ,short int类型是-2^{15}\sim 2^{15} - 1等,由此可以推处-2^{k-1}是下限,2^{k-1} - 1是上限。

当有符号数的数字溢出范围时,又会重新回到所属数据类型的最大或最小值,这与取模运算后数值会在有限范围内类似,取模运算除数为\left (2^{k-1}-1 \right ) -\left (-2^{k-1} \right ) +1=2^{k}-1+1

32位机器上,针对减法,设有整数m和n(m,n均大于0),m - n的值根据取模原理实际可以写成以下形式:

m - n + 2^{k} - 1 + 1 = m + [ (- n + 2^{k} - 1) + 1 ]

以上等式可以描述为m的补码 + ( -n的反码+1 ),也就是m和n的补码相加。

 举个例子:计算 1 - 1 的值。

1的补码为:

-1的反码为:

 根据推导公式,- n + 2^{k} - 1 ,此时n = 12^{k} - 2 在32位机器上的二进制表示如下:

 -1的补码为:

根据推导公式,(- n + 2^{k} - 1) + 1n = 1。在32位机器上的二进制表示如下:

 由于1的补码为其原码:

 两数补码相加后得到值为0。

而正数加法则无需这种变化,原反补的值都相同。

2.3 整型类型与范围

类型范围
char0 ~ 127
signed char-127 ~ 127
unsigned char0 ~ 255
short int-32767 ~ 32767
unsigned short int0 ~ 65535
int -32767 ~ 32767
unsigned int0 ~ 65535
long int -2147483647 ~ 2147483647
unsigned long int 0 ~ 429496 7295


3、浮点型在内存中的存储

先看一段代码,在该代码片段中,分别打印整数num的值与强转浮点型后的值。

int main()
{
	int num = 5;
	float* ptr_num = (float*)&num;
	printf("num = %d\n", num);
	printf("* ptr_num = %f", *ptr_num);
	return 0;
}

运行结果如下:

 按照我们的理解整数强转浮点型打印结果应该为5和5.0。然而打印结果并不一致,说明浮点型的存储与整型存储方式并不一样。

3.1 IEEE754标准

IEEE754二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。

该标准认为任意浮点数都可以表示为(-1) ^ S* M * 2 ^ E

其中,(-1) ^ S为符号位 S = 0 为正数,S = 1 为负数 ;

M为有效数字,取值范围1 < M < 2,在存储时只存储小数部分,如1.01只存储01,这样可以提高数据的精度;

E为指数,标准规定E以unsigned int 形式存储,由于E可能为负数,所以标准规定存入内存时真实值需加上一个中间值,单精度浮点型中间值为127,双精度浮点型中间值为1023,如E = 10时单精度浮点型内存中存储的应为137,二进制形式10001001

E全为0时,则根据上述规则,该浮点数表示的是趋向于0的一个数,对于这种情况,标准规定有效数字M不再还原第一位的1,而是还原为0.x...x的小数部分以此表示趋近于0的正负数。

E全为1时, 根据上述规则,该浮点数表示的是一个数趋向无穷大的一个数。

十进制与IEEE754标准转化:

5.0转化为IEEE754标准写作:\left ( -1 \right )^{0}*1.01*2^{2}

 -5.0转化为IEEE754标准写作:\left ( -1 \right )^{1}*1.01*2^{2}

3.1.1 浮点型 内存存储

对于单精度浮点型,标准规定符号位占1bit,指数占8bit,有效数字占23bit。

 对于双精度浮点型,标准规定符号位占1bit,指数占11bit,有效数字占52bit。

根据内存存储形式,再来看一下这段代码

int main()
{
	int num = 5;
	float* ptr_num = (float*)&num;
	printf("num = %d\n", num);
	printf("* ptr_num = %f", *ptr_num);
	return 0;
}

num整数在二进制中的存储为:

 将其强转为单精度浮点型后:

 此时指数位E均为0,根据标准规定在浮点型中表示的就是一个无限趋近于0的数,所以呈现出的运行结果。

 


END 

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOUZH_093

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值