C语言之路第十五天:数据的存储(二)

浮点数在内存中的存储

首先先看E的使用,即1E10=1.0*10^10

浮点数包括:float, double, long double

 在我们第一次看到这个代码的时候,我们认为结果打印的是9,但是这个程序只有在相同存储类型和打印类型下才会是9,这就充分说明了整型和浮点型在内存中的存储方式不同。上一篇文章我们已经学习了整型的存储方式,那么浮点型的存储方式又是怎么样的呢?

其实浮点型的存储有一个国际标准:IEEE754标准:
即任意一个二进制浮点数V可以表示成以下格式:

(-1)^S * M * 2^E

(-1)^s表示符号位,当s=0时,V为正数;当s=1时V为负数

   M表示有效数字,大于等于1,小于2

   2^E表示指数位

运用以上原则,对于一个浮点数9.0化为上述格式:

9的二进制:1001.0

正数,s=0;M=1.001;小数点向右移动3位,E=3

则化为上述形式:(-1)^0  *  1.001 * 2^3

对于参数S,M,E的解释:

S:如果数字为负数则S为1,如果为正数则S为0;

M:M是有效数字,将二进制进行小数点移位,使其大于1小于2得到的

E:小数点移动几位就是几

根据IEEE754标准:对于32位的浮点数,最高位是s,接着的八位是指数E,剩下的23位是有效数字M,如下图:

 对于64位的浮点数,最高位是S,接着11位是E,最后52位是M,如下图 :

对于E和M的一些特别规定

M:由于M总是1.xxx,因此在存M的时候,整数部分1不存进去,在拿出来的时候再加上,

如上面的1.001,在存M的时候,只存001,要使用的时候在补1即可

E:首先E是一个无符号整数,这就意味着,如果E是8位的,它的范围是0~255,如果E是11位的它的范围是:0-2047;但是在科学计数法中E可能是负数,那该如何解决这个问题呢?E必须在真实值的基础上加一个中间值,对于8位的是127,11位的是1023;

对于上面的3,在存成32位浮点数E存=3+127;存为64位浮点数E存=3+1023

接下来看对于一个浮点数的存储

先化为二进制,再计算S,M,E 写出对于的二进制位,再化为16进制 ,E要加中间值

从内存中存取浮点数:

1,看首位:是1为符,是0为正

2,取M,记得M取出来的是小数部分,使用的时候补1

3,取E,有以下三种形式

        E不全为0或不全为1:

        E-中间值(127或1023)得到,真实E即可

       

        E全为0:

        在32位上是+127后全为0,在64位上是+1023后全是0;因此E的真实值分别为:

        1-127,1-1023

        由于此时这个数接近无限小,此时对M的值会有影响,M不再补1,直接是0.xxx

        此时化回去有效值不用+1,即+-0.xxx *(1-127),或者+-0.xxx * 2^(1-1023)

        E全为1:

        E真+127=255,E真为128,此时这个数趋近于正负无穷大。

最后让我们回到一开始,为时候会不按我们设想输出呢?

为什么第二个打印的是0.000000?

首先int 9在内存中存储的是:00000000000000000000000000001001,如果是按照浮点数取出:E为00000000,则由上可知,这个浮点数取出是无穷小,因此是0.000000

为什么3个打印的是1091567616?

首先这个数是按照浮点数存进去的,

9:1001.0

标准形式:(-1)^0  *  1.001 * 2^3

3+127=130,130化为二进制是:10000010

则存在内存中:0 10000010 00100000000000000000000

这是存进去的补码,以整型打印就是1091567616

由上述可以知道,不同的原因是因为整型和浮点型在内存中的存储和取出方式不同。

        

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值