浮点数在内存中的存储总结

1.浮点数家族:float ,double, long double
首先应明确,浮点数和整数的存储是不一样的。
先来看一个浮点数存储的例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int n = 9;
	float *pFloat = (float *)&n;//将n强制类型转换为float *型,赋值左右两边的类型要一致
	printf("n的值为:%d\n", n);//9
	printf("*pFloat的值为:%f\n", *pFloat);//0.000000
	*pFloat = 9.0;
	printf("num的值为:%d\n", n);//1091567616
	printf("*pFloat的值为:%f\n", *pFloat);//9.000000
	system("pause");
	return 0;
}

四次输出的都不一样,为什么会是这样的结果呢?要解决这个问题就需要彻底搞懂浮点数在内存中到底是如何存储的。
我们知道任何数都有它的科学计数法,类比到这里,浮点数也有类似的表示:
(-1)^ S
M*2^E =====>这里的s表示正负(1 负,0 正) M表示有效数字 2^E表示指数位
对于32位的浮点数(4字节),最高位为S占一个比特位,接下来是占8个比特位的E,剩下的23个比特位留给M(这里M只保存小数点后的部分)
知道了这些,解释上一段代码的结果也就不难了,下面来用一个具体的例子来理解浮点数在内存中的存储:
例如十进制的5.0
写成二进制是101.0,相当于1.01*2^2,那么s=0,M=1.01(实际存的话存的是01,存小数点后面的部分),E=2.
在这里插入图片描述
对于有效数字M和E,还有一些特殊的规定。1<=M<2,所以M在内存中只存小数点后面的部分。
2.指数 E
对于指数E也有很多要注意的地方,首先E为一个无符号整数(unsigned int )对于8位的E,取值范围是(0~ 255),对于11位的E,取值范围又是(0~2047)。但是科学计数法中E也可以是负数,所以内存时E的真实值要加上一个中间数,对于8位的E中间数为127,对于11位的E中间数是1023,

  • 对于E不全为0或不全为1:指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的 1,带入科学计数法的公式就可以得到该浮点数。
    *E全为0:表示接近于0的很小的数字。
  • E全为1:如果有效数字M全为0,表示接近于0的很小的数或者无穷大的数(取决于符号位S)。
    浮点数和整数在内存中的存储是有本质上的区别的。
    最后让我们来解释一下开始的那个疑问,
    9--------> 0000 0000 0000 0000 0000 0000 0000 1001
    可以看出s=0(表示正数) E为全0 M=000 0000 0000 0000 0000 1001
    带入公式得到:(-1)^0 * 0.00000000000000000001001 *2 ^(-146) 显然这是一个接近于0 的正数,所以用十进制表示就是0.000000
    当浮点数为 9.0时:先用二进制表示(存)9.0--------> 1001.0 ——>(-1)^1.001 *2 ^ 3 ——> S=0,M=1.001,E=3+127=130
    则在内存中的形式为:0 10000010 001 0000 0000 0000 0000 0000
    这个数还原成十进制就是1091567616
    至此,浮点数在内存中的存储基本上了解清楚,它和整数在内存中的存储也一样,这里需要知道浮点数的科学记数法的表示,知道浮点数怎么存在32个比特位中又是如何取出的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值