理解:浮点数在内存中的存储

首先我们先来引入一个例子:

int main()
{
	int n = 9;
	float* pFloat = (float*)&n;//
	printf("n的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	*pFloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pFloat的值为:%f\n", *pFloat);
	return 0;
}

这串代码的输出结果是:
在这里插入图片描述
这个结果可能和我们预想的不同,那么为什么会产生这种差异呢?
这里必须得了解浮点数在内存中的存储。

浮点数在内存中的存储:

根据国际标准IEEE 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
V = (−1) ^S * M * 2^E
注意:
^表示指数
*表示乘号
符号含义:
-1^S决定这个浮点数的正负,S为0代表正,S为1代表负
M表示这个数的有效位数,1<=M<2
2^E表示指数位

这里举个简单的栗子:
十进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2 。

那么这S,M,E该如何确定呢?

IEEE 754规定:
对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M
图为32位:
在这里插入图片描述
注意:S,M,E的存储顺序

浮点数的存过程:

对于M:

由于M是大于等于1小于2的,所以计算机在存储时默认舍去1,只保存后面的部分,当读取时再加上1,这样就可以省下来一位的空间,E就可以多保留一位

对于E:

E为⼀个无符号整数。但是,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。

举个栗子:2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

浮点数取的过程:

浮点数取的情况有点复杂,分为三种情况:

情况一:E不全为0或者1—>即为正常数字

这种就是存储时的反操作,将当时加的127(或1023)减去
,得到真实值,再将有效数字M前加上第⼀位的1。

情况二:E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,而是还原为0.xxxxxx的小数。
这样做是为了表示±0,以及接近于0的很小的数字。

可以这样理解:2^(1-127)次方本身就是一个很小的数字了,前面所乘的对这个值的改变不大,仍然是趋近于0的

情况三:E全为1

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

可以这样理解:11111111这个指数本身就很大了,减去127后,2^(255-127)仍然是一个很大的数字,趋向于无穷大

了解了以上知识,我们来解决刚开始的栗子:

int n=9时

定义成int类型的,且大于0,他的原码,反码,补码相同
整数在计算机中以补码的形式存储:
补码为:00000000 00000000 00000000 00001001
以%d打印时:以上的补码被按照整数的形式来打印
以%f打印时,这段补码被当作浮点数看待
0 00000000 00000000000000000001001
分别为S,E,M
由于E为0,由情况二知为0,再由%f确定有效位数
所以最终输出为0.000000

*pFloat=9时:

由于其是float类型的,因此9.0存储时按照浮点数的存储方式
二进制:1001.0—>(-1)^S1.001 * 2^3
则:
在内存中的存储为:
0 10000010 00100000000000000000000
依次为S E M
以%d打印:从整数的形式看就是
01000001000100000000000000000000表示的十进制数,转化后即为打印的值
以%f打印,就是将存的操作倒着来,所以打印的值仍为9,小数点后保留的位数由%f决定

以上就是本次所有内容,希望对大家有所帮助,谢谢观看。

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值