单精度浮点数的存储-转自hb.g@163.com

单精度浮点数的存

首先声明一点:由于我所能看到的讲编码的书都是一帮 SB 写的狗屎,所以对于单精度浮点数的存储,我也不敢说已彻底掌握, 下面也只是小弟的一些不成熟的心得,不对之处恳请指正!

 

先贴一个输出单精度浮点数二进制代码的程序

/*

      2007-5-22

      修改于 2007 10 27 16:46:12   沙坡村 IBM

     

      将一个单精度浮点数的二进制数字显示出来

*/

# include <stdio.h>

 

int main(void)

{

      float a = -33.33f; //-33.33f 是个很有代表型的数字,它再一次证明了浮点数是不能精确存储的

      unsigned int* p = (unsigned int* )&a;

      int len = sizeof(float);

      int i;

      char k;

 

      printf("a = %f/n",a);

      for (i=31; i>=0; --i)

      {

           k = (*p)>>i  & 1;

           printf("%d ",k);

 

           if (31== i || 23==i)

                 printf(" - ");

      }   

      printf("/n");

 

      return 0;

}

/*

      具体的若干次输出结果是:

***********************

a = -5.000000

1  - 1 0 0 0 0 0 0 1  - 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Press any key to continue

***********************

a = 5.000000

0  - 1 0 0 0 0 0 0 1  - 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Press any key to continue

*************************

a = 12.687500

0  - 1 0 0 0 0 0 1 0  - 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Press any key to continue

*************************

a = -12.687500

1  - 1 0 0 0 0 0 1 0  - 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Press any key to continue

*************************

a = 0.810000

0  - 0 1 1 1 1 1 1 0  - 1 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 1

Press any key to continue

*************************

a = -0.810000

1  - 0 1 1 1 1 1 1 0  - 1 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 1

Press any key to continue

*************************

a = -33.330002

1  - 1 0 0 0 0 1 0 0  - 0 0 0 0 1 0 1 0 1 0 1 0 0 0 1 1 1 1 0 1 1 0 0

Press any key to continue

*************************

*/

 

下面我再谈谈自己的看法:

 

      浮点数的表示分三部分:

           符号位     阶码     数字位   

      比如: 123.45678 在内存中的表示就是 +    2   1.2345678               1 * 12345678*102

              - 123.45678  在内存中的表示就是 -    2  12345678              -1 * 12345678*102

              1879978.3  在内存中的表示就是 +     6   1.8799783              1 * 18799783*106

              -1879978.3 在内存中的表示就是   -     6   1.8799783           -1 * 18799783*106

       换句话说符号位表示该数字的正负,数字位可以先暂时认为表示这个数字到底是那几个数字,阶码表示的是 10 的某次方,阶码刚好确定了该数字的小数点的位置

     

      当然这只是一种比喻,实际内存中只有由 0 1 组成的代码,阶码不是 10 的某次方,而是 2 的某次方,数字位也是在某种编码规则下的 01 代码组成,符号位是用 1 表示负,用 0 表示正。

      待会我们再详细讨论这个问题。

 

      浮点数当然也分为 1 、正的浮点数    2 、零    3 、负的浮点数,

下面我分别讨论这三类数的存储 !

     

一、零的二进制代码无论是整数型,还是字符型,还是浮点型,都是0

     

二、正浮点数的二进制代码

    12.6875f 为例, 我们可以先将 12.6875f 转化为二进制数字, 12 的二进制是 1100,  0. 6875 的二进制是 0.1011, 【此处省略了整数和小数的二进制求法,不懂者可参阅相关书籍】 , 12.6875f 的二进制是 1100.1011,

一般情况下,浮点数是以 IEEE754 标准来存储的,即以

(-1)S * (1.f)*2e-127

来存储的 , 并规定如果该数字是单精度浮点数,则 s 1 位, e 8 位, f 23

s 就是我上面所说的 符号位   f 就是我上面所说的 数字位 e 就是上面所说的阶码 注意不是 1.f ,也就是说我们存储的是 f 而不是 1.f OK   如果看不明白,没关系,请继续往下看

好,再回到 12.6875f 这个数字,我们已求得它的二进制是 1100.1011, 套用 IEEE754 标准

(-1)S * (1.f)*2e-127

 

就是 (-1)0 * (1.1001011) * 2 130-127

 

s 就是 0 f 就是 1001011,  e 就是 130

130 的二进制就是 1000  0010

又得知 s 1 位, f 23 位, e 8

e 就是 1000  0010 

s 0

f 就是 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

12.6875f 的二进制代码是

0      1000  0010        1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

     

二、负浮点数的二进制代码

负浮点数 的二进制代码和与它所绝对值相等的正浮点数 的代码几乎是一摸一样的,唯一的不同的是把s0 改为了1 ,即把第一个位由0 改为了1 ,其余位的二进制代码都是一样的

入:

-5.000000  的二进制代码是

1  - 1 0 0 0 0 0 0 1  - 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

5.000000   的二进制代码是

0  - 1 0 0 0 0 0 0 1  - 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

 

12.687500  的二进制代码是

0  - 1 0 0 0 0 0 1 0  - 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

-12.687500 的二进制代码是

1  - 1 0 0 0 0 0 1 0  - 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

 

0.810000  的二进制代码是

0  - 0 1 1 1 1 1 1 0  - 1 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 1

-0.810000 的二进制代码是

1  - 0 1 1 1 1 1 1 0  - 1 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 1

      我的 Email   hb.g@163.com , 不对之处,恳请诸位诸位发邮件指正

                

                                                                                                                                                                        2007 10 28

                                                                              西安

 

首先,我们需要将-6.625转换为二进制数。这可以通过以下步骤完成: 1. 将6转换为二进制数:110 2. 将0.625转换为二进制数:0.101 现在我们将这两个二进制数组合起来,得到-6.625的二进制表示:110.101 接下来,我们需要将这个二进制数转换为科学计数法。首先,我们将小数点向左移动,直到只剩下一个非零数字。在这种情况下,我们需要将小数点向左移动两个位置,得到1.10101。 现在,我们需要将这个二进制数标准化,即将小数点移动到第一个非零数字前面。在这种情况下,我们需要将小数点向右移动一位,得到11.0101。 最后,我们需要将这个二进制数转换为科学计数法。在这种情况下,指数为1,因为我们将小数点向右移动了一位。因此,我们的科学计数法表示为:-1.10101 x 2^1。 现在,我们可以将这个科学计数法表示为IEEE 754单精度浮点数。首先,我们需要确定符号位。因为这是一个负数,符号位为1。 接下来,我们需要将指数位表示为8位二进制数。指数为1,加上偏移量127,得到128。因此,指数位为10000000。 最后,我们需要将尾数位表示为23位二进制数。我们将11.0101转换为二进制数,得到1.10101000000000000000000。 现在,我们可以将这些位组合起来,得到IEEE 754单精度浮点数表示为:1 10000000 10101000000000000000000。 因此,用IEEE 754 32位单精度浮点数表示-6.625的结果为:11000000110101000000000000000000。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值