数据在内存中的存储——浮点数

塞翁失马,焉知非福。——《淮南子·人间训》


1、介绍

常见的浮点数:3.1415926,1E10等,浮点数包含的类型有float,double,long double
浮点数的表示范围在头文件float.h中定义。

2、由题引入

下面,我们来看一段代码,来观察一下,究竟最后打印出来的是什么?
在这里插入图片描述
又是不经的发出疑问,为什么到这却是那么多和自己想的不一样的地方啊!到最后就只对了一半?
那么到这我们就应该想一下,到底是为什么,难道是之前对于整型的存储的理解到浮点数就不同了?难不成浮点数的存储方式,和我们想的完全不一样吗?

3、浮点数的储存

上面的代码中明明,num和*pFloat就是一个数,为什么浮点数和整数的解读结果会差别那么大?
那么为了搞清为什么是这样的结果,我们必须搞明白浮点数在计算机内部的表示方法。
根据国际标准IEEE(电气和电子工程协会)754 任意一个以二进制浮点数V可以表示成一下的形式
在这里插入图片描述
为了更好的理解,通过举例来说明
就以十进制的5.0来说,写为二进制的话是101.0,相当于是1.01 *2^2。
按照上面的V的形式,可以得出S=0,M=1.01,E=2
相同的,那要是-5的话,写为二进制的话是-101.0,相当于是-1.01 *2^2。那么,S=1,M=1.01,E=2
同时IEEE754规定:
1、对于32位的浮点数来说,最高位的1位存储的是符号位S,接着的8位存储指数E,剩下的23位存储有效数字M。
2、对于64位的浮点数来说,最高位的1位存储的是符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。
下面是对于32位来说的简图在这里插入图片描述
下面是对于64位来说的简图
在这里插入图片描述

4、浮点数的存取的过程

4、1浮点数的存

由于对于M来说,已经规定了M的取值范围,1<M<=2的,所以对于M来说,既然必定会是1.xxxx什么的,那还有必要存储吗?有必要浪费一个字节吗,如果不存,还可以更精确。
所以根据IEEE规定,每次保存的时候都是把1舍去只保留小数点后面的数字。只有到时候读取的时候,才会把原来的1加上去。
但是对于E来说,还是情况比较复杂的
首先E是一个无符号的整型,由于是8/11个字节,所以取值范围应该是0~ 255/0~2047:但是难道所有的浮点数都是大于1的?难道科学计数法中就没有负数出现吗?很显然,当然是有的啊。所以IEEE又754规定了,对于存入的E的真实值必须加上一个中间值,对于8/11位的E来说,中间值是127/1023.比如,2^10的E是10,所以在保存成为32位的浮点数的时候,必须是10+127=137,保存10001001。

4、2浮点数的取

指数E从内存中取出的过程还可以分为三种情况:
1、E不全为0或者不全为1
那就按照上面的正常方法进行,先S后E最后M的方式一个个取出。
2、E全为0
那么这时,还得再减去127或者1023才能是最后的E,那么可想而知,会是一个很小的数字,那么此时,在有效数字M不会再前面加上第一位的1,相当于就是0.xxxx表示一个很小的数字,这也是方便来表示一个很小的数字。
3、E全为1
这是就相当于是上一个特例的反义词,表示无穷大的意思。

5、题目回顾

在这里插入图片描述
所以我们现在再来看这时候的题目,是不是有一种了解的感觉呢?
首先看第一部分,为什么 指针pFloat变为0?
其实,由于n是整型,所以在存储的时候就会是32个比特,会是 0000 0000 0000 0000 0000 0000 0000 1001
那么变为浮点数的时候,第一位是S=0,E=0此时应该是上面的E全为0的时候,应该是一个很小的数字,所以才会导致最后的结果是0.0000000
看第二部分
既然是浮点数的指针,那么存储的时候会是什么呢?
0(S) 10000010(E) 001 0000 0000 0000 0000 0000(M)
那这段数字转为二进制的整型之后,就是会变得很大,所以最后打印出来的会是那样。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值