内存中数据的存储(更新了十六进制数大小端存储)

内存中数据的存储(更新了十六进制数大小端存储)


一、整型在数据中的存储

在计算机中整型的表示有三种:原码、反码、补码

三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位正负表示方法不同


原码

将原来整型换算成二进制数

PS : 二进制数如何换算

例子:整数125

笔算:1111101

在这里插入图片描述

或者用计算机里面自带的计算器

在这里插入图片描述


反码

将原码的符号位不变,其他位依次按位取反就可以得到了

反码+1就得到补码

PS:正数的原、反、补码都相同,整型数据存放内存中其实存放的补码


在计算机系统中,数值一律用补码来表示和存储

原因在于,使用补码,可以将符号和数值统一处理,加法和减法也可以统一处理(CPU只有加法器)

补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。


十六进制和整型数据的存储

计算机中,二进制数可以转为十六进制数,一个十六进制数相当于4个2进制,也就是4个bit,两个十六进制数为一个字节

大端:数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中

小端:数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中

例子:

int a = 0x123;
//在内存中,int类型有4个字节,2个二进制数为一个字节
//所以有8个十六进制进制数
//补齐0是  0x 00 00 01 23
//  数据高位-------------数据地位
//  内存中:
//   大端    00 00 01 23
//   小端    23 01 00 00
//  低地址-----------------高地址

二、浮点型在数据中的存储

根据国际标准IEEE(电气和电子工程协会)

任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S * M * 2^E (-1)^s 表示符号位

当s=0,V为正数

当s=1,V为负数

M表示有效数字,大于等于1,小于2

2^E表示指数位


十进制数 5.5 如何转化为二进制数字

先看整数部分:5即为101 ( 1*2^2 + 0*2^1 + 1*2^0 = 5 )

而小数部分:0.5即为.1 (1*2^-1 = 0.5)

其他小数以此类推


如何将此小数用IEEE标准表示

先将5.5的二进制数变成科学计数法

101.1 = 1.011 * 2 ^ 2 (因为移动了 两位数,类比十进制的10 ^ 2)

s = 1;M = 1.011;E = 2(移动了2位);

但一些特殊的数字

比如 3.3

11.?? 再去用2的负1负2这种去表示表示不完,结果会四舍五入保存

所以浮点型的数字只需要保存SME就可以


针对float类型而言(4btye)

在这里插入图片描述

S是直接放进去,而EM值则为与EM相关的数值存进去


针对double类型(8btye)

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

在这里插入图片描述


但IEEE 754 指出

关于M

M永远 1≤M<2 ,也就是说,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分

比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目 的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。


关于E

首先,E为一个**无符号整数(unsigned int) **这意味着,如果E为8位,它的取值范围为0-255;如果E为11位,它的取值范围为0-2047。但是,我们知道,科学计数法中的E是可以出现负数的

所以IEEE 754规定

存入内存时E的真实值必须再加上一个数对于8位的E,这个数是127;对于11位的E,这个数是1023。比如,2^10的E是10,所以保存 成32位浮点数时,必须保存成10+127=137,即10001001


最后来看5.5究竟是怎么存储到内存的

因为是正数,所以S = 0

因为二进制数的科学计数法是 101.1 = 1.011 * 2 ^ 2

所以M = 1.011

同理,E = 2

但在内存中E = 2 + 127 =129

S E M

1 0100 0001 0110 0000 0000 0000 0000 000

八个比特位为一组(1byte)

10100000 10110000 00000000 00000000

​ 40 B0 00 00

在内存中是 00 00 B0 40 存储(小端)


前面说明E存在内存中的情况,指数E从内存中取出还可以再分成三种情况:

**E不全为0或不全为1 **

指数E的值为E减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。


E全为0

此时如果E为0,按照原来的E = -127 ,而 2^-127次方表示很小的数字.

所以规定指数E等于1-127(或者1-1023)即为真实值,有效数字M为0.xxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。


E全为1

如果是float类型,真实的E为255 - 127 = 128 ,2^128很大

如果有效数字M全为0,表示±无穷大(正负取决于符号位s);


再看一道题

int main()
{
	int n = 9;
    //正数 S = 0
	//0 00000000 00000000000000000001001  这是9的补码
	//E为全0
	//E直接就是1-127 = -126
	//M = 0.00000000000000000001001 因为E = 0,所以M以0.xx结尾
	//0.00000000000000000001001 * 2^-126  接近0
	float* pFloat = (float*)&n;//这一步是以float类型取出9
	
	printf("n的值为:%d\n", n);//9
	printf("*pFloat的值为:%f\n", *pFloat);//0.000000

	*pFloat = 9.0;//这一步是将9.0以浮点型存储进去
	//1001.0
	//(-1)^0 * 1.001*2^3
	//S = 0
	//E = 3 + 127 =  130
	//M = 1.001
	//0 1000 0010 0010 0000 0000 0000 0000 000
    //01000001000100000000000000000000 = 1091567616
	printf("num的值为:%d\n", n);//1091567616
	printf("*pFloat的值为:%f\n", *pFloat);//9.000000

	return 0;
}

  • 5
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 3
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:终极编程指南 设计师:CSDN官方博客 返回首页
评论 3

打赏作者

凛音Rinne

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值