数据在内存中的储存——整数/浮点数


整理不易,3连走起

1.整数的储存

★整数有3种形式,原码,反码,补码。整数在内存中是以二进制的补码形式保存的。有符号整数的最高位是符号位,0表示正,1表示负,其余位都是数值位。

★正整数的原反补相同。

★负数的原码是这个数的二进制。反码是除符号位,其他位按位取反。反码+1就是补码。同样的,负整数的反码除符号位之外其他位按位取反之后+1即为原码。

★例:-15的原反补转换
  -15  的原反补转换

1.1整数的计算

★整数在内存中都是以二进制补码的形式储存的,计算也是计算的二进制补码。

★cpu只有加法器(加法的硬件电路),用补码进行运算可以统一处理符号位和数值位,不需要其他的硬件电路。

★乘除法的本质也是加法,比如3×4的本质是3+3+3+3。

★例:-9与5的和的计算
(统一处理了符号位)
  整数的二进制补码运算

2.浮点数的储存

★浮点数的保存方式是国际标准IEEE754(电子电气协会)定义的。

★浮点数在内存中会单独保存符号,有效数字,指数。
整数的二进制位表示的是2 ^0 , 2 ^1 , 2 ^2 , 2 ^3 , 2 ^4 , 2 ^5……
浮点数的小数部分各小数位分别是 2 ^-1, 2 ^-2, 2 ^-3, 2 ^-4……
即 0.5,0.25,0.125,0.0625,0.03125.……

★浮点数的表示公式:V = (-1)^ S × M × 2^E
S:正负号,0为正数,1为负数
M:(二进制)有效数字,1<M<2
2^E:指数(unsigned int)

★浮点数的储存规则
在这里插入图片描述

★ 例: float类型的 -5.875
-5.875是个负数——>所以最高位为1——>(-1)^S==-1,
S== 1;
-5.875的数值位用二进制表示为101.111(小数字部分为0.5+0.25+0.125),科学计数法表示为1.01111×2²(小数点左移两位)
对于32位float的浮点数的指数
E== 2+127==129——>1000 0001
M只保存小数点后的部分,即01111,后面补0
所以float类型(32位)的-5.875在内存中是这样保存的
1 10000001 01110000000000000000000
   -5.875  的储存

★浮点数的存取注意事项:
┅因为E有可能是负数,所以对于32位浮点数的E,在保存的时候,要加上127。对于64位浮点数的E要加上1023。
┅从内存中取E的时候,要根据浮点数的位数减去127或者1023。
┅另外,E为全1的时候,真实的E为255-127,这么大的指数,代表小数点左移了128位,即整数部分是二进制是2^128,我们定义这个浮点数位无穷大。反之E为全0的时候,表示无限小)

2.1浮点数与整数的转换问题

★将一个整数用浮点数的形式读出来,或者将一个浮点数用整数的形式读出来,都是直接读的对方的二进制位。

★例(以浮点数的形式读取整数):

#include<stdio.h>
int main()
{
	int a = 1105461248;       //0  10000011  11001000000000000000000
	printf("%d\n", a);        //E==131-127==4(表示小数点向左移动了4位)
	float* p = (float*)& a;   //M=11001(二进制科学计数法小数点后面的值)
	printf("%f\n", *p);       //科学计数法:1.11001×2^4
	                          //即:11100.1  转换为十进制即为28.5
	return 0;
}

★以上代码的运行结果
在这里插入图片描述

3.大小端字节序

★大小端字节序指的是数据在内存中的存储顺序。
★数据的低位存在高地址处还是低地址处?

★由于内存的地址分配单位是字节(8bit),所以对于2字节及以上的数据必须分字节存储
比如int类型的0000 0000 0000 1111 0000 0000 0000 0001
它的4个字节分别为00 0F 00 01 那么这4个字节都有对应的地址,不同的编译器会用不同的顺序存储。

★低位存在地地址处的是小端字节序
★低位存在高地址处的是大端字节序

★例:
在这里插入图片描述

★如何判断在当前编译器上的大小端字节序

★用程序表示1:

#include<stdio.h>
void test(int* a)
{
	if (*(char*)a == 1)
	{
		printf("小端字节序");
	}
	else
	{
		printf("大端字节序");
	}
}

int main()
{
	int a = 1;
	test(&a);
	return 0;
}

★用联合体(共用体)/结构体的方式

#include<stdio.h>

union lty
{
	int a;
	struct ytl
	{
		char b;
		char c;
		char d;
		char e;
	}m;
}yy;

int main()
{
	yy.a = 1;
	if (yy.m.b == 1)
	{
		printf("小端字节序");
	}
	else
	{
		printf("大端字节序");
	}

	return 0;
}

3.1结构体联合体在下一章

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值