浮点数在内存中的存储方式

我们以一个例题,来进入对浮点数在内存中如何储存的探讨

浮点数储存的例子:

第一个与最后一个打印9没有问题

n是个整数,放入的时候是9,但是pFloat是一个浮点型的指针,会按照浮点型的形式取出数据,

当我再看num的值的时候,我是以整型的方式看的,但是num按照浮点型的方法储存的,最终拿不到想要的结构,是因为整型与浮点型的储存方式不一样

根据国际标准IEEE,任何一种二进制浮点数,都可以写成V=(-1)^S*M*2^E

(-1)^s表示符号位,当S=0时,表示一个正数,当S=1的时候,表示一个负数

  M表示有效数字,大于等于1,小于2的数字,2^E表述指数

V=5.0f;   101.0(二进制)

浮点数,是指小数点可以移动,如果小数点向左移动两位,1.01*2^2

现在这个V可以二进制写成(-1)^0*1.01*2^2

V=9.5时。V=1001.1

=1.0011*2^3

=(-1)^0*1.0011*2^3

但是浮点数是有可能无法精确计算的,当V=9.6时,你会发现小数部分没有任何一个魏晋至数字能精确的表示,所以浮点数有时候是不精准的

在内存中,对于浮点数V=(-1)^S*M*2^E我们只需要存S,M,E就可以了

对于float类型

对于double类型

IEEE754对于M与E还有一定的约束

前面说过,1<=M<=2,也就是说,M可以写成1.xxxxxxxx的形式,xxxxxxx表示小数部分

IEEE754规定,在计算机内部保存M的时候,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分,比如保存1.01的时候,只保存01,等读取的时候,再把第一位的1加上去,这样做的目的,是节省1为的有效数字,以32位浮点数为例,留给M的只有23位,将第一位的1舍去之后,可以保留24位有效数字

但是我们知道E可以是负数,比如储存0.5的时候,但是E是一个无符号数,所以,IEEE754规定,存入内存的时候,必须再加上一个中间数,对于8位的E这个中间数是127,对于11位的E这个中间数是1023

当E的值小于127或者1023时,用来表示负数。

现在我们储存一个float  f=5.5;

那么s=0  m=1.011  e=(2+127)=129

首先储存s 0

之后储存e 10000001

之后储存011

0 10000001 011 0000000000000000000000000

按照字节排序

0100  0000 1011 0000 0000 0000 0000 0000

换成16进制

40    b0   00   00

这里涉及到小端的问题,应该是倒着放的

我们取地址来看看

我们上述的是浮点数怎么放进内存中去,那怎么从内存中拿出来呢?

取出来分为三种情况

  1. E不全为0或不全为1

    这时,浮点数采用下面的规则表示,即指数E的计算值减去127(或者1023),得到真实值,再将有效数字M迁加上第一位的1

  1. E为全0

    这时,浮点数的指数等于1-127(或者1-1023)为真实值

有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示+-0,以及接近于0的很小的数字

  1. E为全1

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

在了解这些规则之后,我们再来看文章一开始的这个题目

n的二进制序列为0000 0000 0000 0000 0000 0000 0000 1001

第一个9没有问题,以整数形式放入,以整数形式拿出来

在第二个的时候,我们将上述的0000 0000 0000 0000 0000 0000 0000 1001放入内存时候,内存是以浮点型的角度去看这个数的

它的E全为零,也就是指数为全零,那就是-126

M还原出来就是0.000 0000 0000 0000 0000 1001

那这个值应该是0.000 0000 0000 0000 0000 1001*2^-126,这个值已经小的没边儿了,是一个无限接近于零的数字,就算float打印出后六位小数,也只能打印出0,所以第二个打印出了0.000000

那么接下来,我们*pFloat-9.0;以float的形式放入了这个数字

第四个按照浮点形式放,浮点形式取出,是9没有问题

那第三行怎么回事?

9.0怎么存,是1.001*2^3

S=0   E=3  M=1.001

0  100 00010  001 00000000000000000000

0100   0001  0001  0000  0000  0000  0000  0000

这就是我们以浮点数的形式放入了这个数字,那这四个字节按这种方式存了进去

我们第三行打印出的时候,是按照整型的方式打印的,1一看是正数,那这个就是整形的补码

那这个数字就会以整形的方式读取,就是这个数字1000001000100000000000000000000

这个十进制1091567616的结构与我们计算出来的毫无差异

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值