数据在内存当中的存储(浮点数,整形存储,大小端)

目录

浮点数篇

大小端的介绍即判断

整形在内存中的存储


浮点数篇

        首先说 浮点数家族包括: float double long double 类型。 浮点数表示的范围: float.h 中定义。首先我们先来看这样一个例子:

 前后声明的值都为9,但是在整形类型输出和浮点数类型输出时产生明显的差异,就说明整数类型和浮点数类型在内存当中存储的形式是完全不同的。那么浮点数类型在数组当中是怎样存储和取出的呢?

(一)浮点数类型在内存当中的存储

        
        根据国际标准IEEE (电气和电子工程协会) 754 ,任意一个二进制浮点数 V 可以表示成下面的形式: (-1)^S * M * 2^E。
(-1)^s表示**符号位**,当s=0,V为正数;当s=1,V为负数。
M表示**有效数字**,大于等于1,小于2。
2^E表示**指数位**。
(1)首先要熟练完成这样的转换:

  例1: (十进制 )5.5->101.1(二进制),即(-1)^0 * 1.011 * 2^2。此时,S=0; M=1.011; E=2;
二进制表达为:0 10000000 01100000000000000000000
例2:(十进制)9.0->1001.0(二进制),即(-1)^0 * 1.001* 2^3.此时S=0;M=1.001;E=3;
二进制表达为:0 11000000 00100000000000000000000
(2)其次要明白在内存当中的存储安排和规则
安排如下图:

 

 

规则:

1.S是0就放0,是1就放1;

2.由于E可能出现负数,即0.5就是2的负一次方,E=-1。这是由于八位存储可以最大范围(不同平台范围会有差异)是0~255,规定存储时将原来的E0+127(范围的中间值)=E(新E),转换为二进制位后存储到八位当中。比如,2^10的E 是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

3.M因为是大于等于1,小于2,所以存储时去掉1,只保存小数点后面的数。这样可以保存到小数点后24位,相比于保存1,只保存到小数点后23位来说更加精确。并且如果不到23位后面自动补0。

这里我们根据上述分析一个存储的例子:

 

(二)浮点数取出(因E而不同)

        1.E这8位不全位0或者不全为1。这时浮点数正常E-127=E0,得到真实值,再将有效数字M前面加上1。例如0.5:

0 01111110 00000000000000000000000

        2.E全为0。这时浮点数E直接等于1-127=-126;M不加1,直接取0.xxxxxx,这样的小数,这样做的目的是表示+-0,十分接近0 的一个数字。原因:E=0,即E0+127=0->E0=-127.2^(-127)这个数字太小了,所以出此上策。

        3.E全为1。二进制位表示255,255-127=128,2^128,这个数字非常大。所以直接表示+-无穷大。

这样就可以解释之前的那个例子了。相关注释在代码中:

#include <stdio.h>
int main()
{
	int n = 9;
	//正数原码反码补码相同
	//二进制序列为:
	//00000000 00000000 00000000 00001001
	//转换为float类型放到内存当中存储默认为:
	//S:0;E:00000000;M:00000000000000000001001
	//向外取得时候认为E为全0,则E=1-127=-126,M=0.00000000000000000001001
	//%f打印的数字就是:(-1)^0 * 0.00000000000000000001001 * 2^-126无限接近0
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);//以%f打印时默认只能打印到小数点后6位,所以显示0.000000

	*pFloat = 9.0;
	//二进制形式:1001.0
	//(-1)^0 * 1.001 * 2^3
	//S=0;M=1.001;E=3
	//存储时:0 3+127=130 001(不够23位自动在后面补0)
	//即为:0 10000010 00100000000000000000000
	printf("num的值为:%d\n", n);

	//以%d形式打印时,默认将他看为有符号数,二进制换算为十进制为1091567616

	printf("*pFloat的值为:%f\n", *pFloat);

	//float 形式向外取时,E不是全0也不是全1,正常拿取。
	//或者另一种理解,以浮点数形式存储一浮点数形式输出二者的值应该是一样的。
	return 0;
}

大小端的介绍即判断

(一)介绍:

        1. 小端字节序存储:把一个数据的低位放在低地址处,高位放到高地址处。

         2.大端字节序存储:把一个数的低位字节内容放在高地址处,高位字节内容放在低地址处。

##为什么会存在大小端之分?

        每个地址都对应着一个字节,当存储数据将多个字节安排超过一个字节时,就会存在存储顺序的问题。

(二)大小端的判断

 

整形在内存中的存储

        首先,整形在内存当中的存储是以补码的形式进行存储的。这就涉及到两个问题:

(1)原码反码补码的概念:

原码:直接将二进制按照正负数的形式翻译成二进制

反码:原码符号位不变,其他位按位取反

补码:反码加一得到补码

注:1.正整数的原码反码补码相同。

2.符号位不变,原码按位取反再加1得到补码,同样补码按位取反再加一得到原码。

(2)为什么要用反码存储,不用原码?

因为,使用补码,可以将符号位和数值域统一处理。CPU当中只有加法,在运算当中,补码优于原码。举个例子:

如有错误,欢迎指正!让我们一起加油吧!

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值