什么?你还不知道浮点数在内存中的存储?

前言:

上一节我们学习了结构体在内存中的对齐规则,这一节小编主要讲一下浮点数在内存中的存储规则


正文:


浮点数在内存中的存储规则:

我们先来看一个实例:

int main()
{
	int n = 10;
	float* pfloat = (float*)&n;
	printf("n的值是%d\n", n);
	printf("*pfloat的值是%f\n", *pfloat);

	*pfloat = 10;
	printf("n的值是%d\n", n);
	printf("*pfloat的值是%f\n", *pfloat);
	return 0;
}

输出:

n的值是10
*pfloat的值是0.000000
n的值是1092616192
*pfloat的值是10.000000 

我们发现对于同样一组数据,只是改变了打印的方式,区别竟然如此大,这说明浮点数在内存中存储和取出的规则和整数是不一样的,那究竟是怎么样一个规则呢,我们现在来看对齐规则:

国际标准IEEE754规定了任何一个浮点数V在内存中的二进制存储规则:

V   =  (−1) ^S*M*2^E

其中当S = 0时,符号为正,S为负数时,符号为负。

M位是二进制位的有效数字,M必须是大于1小于2的;

E是二进制的指数位。

比如10,二进制是1010,可以写作(-1)^0 *1.01*2^3

其中s = 0,M = 1.01 ,E = 3

IEEE754规定,对于32位,第一位为S,中间8位为E,剩余23位为M,如果不够23位则在,M后面补0;

 浮点数分为存和取两个过程,我们先看存,

 刚刚说了,S是第一个位置,要不为0,要不为1;

M是介于1-2之间的数字,所以在存的过程中,如1.011只会存011然后在其后面补满23个0,在取的过程中,自动加上1.

E:如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我 们知道,科学计数法中的E是可以出现负数的,所以IEEE754规定,存入内存时E的真实值必须再加上 ⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

我们再看取的过程,

S不用管,再最后M的数值上加1,比如M,0.01,最后数值是1.01,这里E分三种情况讨论:

当E是01组成的,E+127

当E是全0,让E = -126,表示无穷小

当E是全1, 表示无穷大

现在我们来分析上面的问题,

第一个是将浮点数取出来,10在内存中的二进制序列为0 00000000 00000000 00000000 00001010

我们按照取的规则,其中第一位 S = 0,

E是全为0的情况,所以E-127

将10以浮点数的二进制形式存起来,(-1)^0 *1.01 *2^3

其中S = 0; M = 00000000 00000000 00001010,E = -126

按照IE754的V规则,写出来是 :(-1)^0   * 00000000 00000000 00001010 *2^(-126)是非常小的一个数字,所以为0

我们再来看第二个:

我们这里是存的规则:

10按照IEEE754可以写作:(-1)^0  *1.01 *2^3

其中S = 0,M = 1.01,E=3

我们现在就按照32位将他们放进去就行了,

如图:

其中S占第一个位置,E:3+127 = 130 ,二进制为1000 0010,刚好是8个bit位;

M去掉1,还剩01再其后面补0,最终32位bit位为:

结果就是1092616192


文末:

看到这里,想必你已经学会了浮点数在内存中是如何存储的,下来也可以多给两组数据,自已尝试,相信你一定能做出来,如果本文有什么错误,也望小伙伴们指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值