float型数在计算机中的表示

本文通过具体示例解析了浮点数在计算机内部的表示方法及其运算原理,并详细解释了为何浮点数相加会出现精度误差。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转:在本科学习《计算机组成原理》这门课的时候曾经详细学习了浮点数在机器中的表示方法,昨天做题时再次偶然遇到浮点数的问题,参考了很多资料总算是对这个问题有了比较全面的认识,总结一下以备查阅。

     我们以一个简单的例子开始对该问题的讨论。 

     #include

​      int main(void){    

              float x,y;     

              x = 111111.111;     

              y = 222222.222;     

              printf("%f\n",x + y);     

              return 0;

​       }

       输出结果不是:333333.333,而是:333333.328125,这是什么原因呢?

       首先​我们先复习一下关于机器中浮点数表示的基本知识点,然后对该问题进行具体的分析和讨论。

       1. 按照IEEE 754的标准,32位浮点数和64位浮点数的标准格式如下所示:

                          31                 |30                      23| 22                             0

       32位浮点数: S(符号位)           E(阶码)                    M(尾数)

                          63                 |62                      52  |51                            0

       64位浮点数: S(符号位)            E(阶码)                   M(尾数)

       不论是32位浮点数还是64位浮点数,规定基数R = 2。由于基数2是固定常数,不必用显式方式来表示它。

       我们可以看到,在32位浮点数中,S是浮点数的符号位,占1位,安排在最高位,S=0表示正数,S=1表示负数。M是尾数,放在低位部分,占用23位,用小数表示,小数点放在尾数的最前面。E是阶码,占用8位,阶符采用隐含方式,即采用移码方法来表示正负指数。采用指数的实际值加上固定的偏移值的办法来表示浮点数的指数,好处是可以用长度为n个比特的无符号整数来表示所有的指数取值,这使得两个浮点数的指数大小的比较更为容易。

      指数偏移值(exponent bias),是指浮点数表示法中的指数域的阶码值E为指数真值e加上某个固定的值,IEEE 754标准中规定该固定值为​2^(n-1) - 1,其中n为存储指数的比特的长度。

      以单精度浮点数(32位)为例,它的指数域有8个比特,固定偏移值是2^(8-1) - 1 = 127.考虑到8比特的无符号整数的范围为:00000000——11111111(即0——255),0和255是特殊值,所以阶码的范围为:1——254,那么单精度浮点数的指数部分的真值范围为:-126——127(1 - 127~254 - 127).

      采用这种方式时,将单精度浮点数的指数真值e变为阶码E时,应将指数e加上一个固定的偏移值127(01111111),即E = e + 127

       一个规格化的32位浮点数x的真值可以表示为

        x = (-1)^S * (1.M)*2^(E- 127)                        e = E - 127

       其中尾数域所表示的值是1.M。因为规格化的浮点数的尾数域最左位(最高有效位)总是1,故这一位经常不予存储,而认为隐藏在小数点的左边。

       64位的浮点数中符号位1位,阶码域11位,尾数域52位,指数偏移值是1023(2^(11-1) - 1).因此规格化的64位浮点数x的真值为

       x = (-1)^S * (1.M) * 2^(E-1023)                       e = E -1023

      为了提高数据的表示精度,当尾数的值不为0时,其绝对值应>= 0.5,即尾数域的最高有效位应为1,否则要采用修改阶码同时左右移动小数点的办法,使其变成这一要求的表示形式,这成为浮点数的规格化表示

     以上就是关于浮点数表示的基本知识。​

     2.按照上述基本理论可得x和y的二进制形式分别如下:

       x: 0,10001111,10110010000001110001110    

       y: 0,10010000,10110010000001110001110

       最左边的位是符号位,接下来的8位是阶码位(下面用E表示),表示2的(E-127)次方,最右边的23位是尾数位(下面用M表示),表示尾数1.M.

        这里主要按照浮点数的表示方法对x进行详细的计算,y的计算过程类同: 

        x的阶码:E = 10001111,转换成10进制则为:143,再减去127,结果为16(二进制形式为:10000)。

        x的尾数部分:M = 1.10110010000001110001110,于是这个二进制的科学计数法则为:

         ​1.10110010000001110001110 x 2^16  (a)

         于是上式(a)变为:11011001000000111.0001110

         按照二进制转换为十进制的步骤,这个二进制数“精确地”转换为十进制数的结果为:111111.109375    

         同理,y的二进制形式为:110110010000001110.001110,精确地转换为十进制的结果为:222222.21875    

        所以程序的结果就很明显了。加起来之后(没有溢出,而且这个例子float没有精度损失),所以结果就是:333333.328125(精确),而非333333.333了。

        参考:计算机组成原理(第三版.网络版) 白中英主编 Page 20-21

                http://tieba.baidu.com/f?kz=847907586

                http://zh.wikipedia.org/zh-cn/IEEE_754

               http://www.cnblogs.com/bossin/archive/2007/04/08/704567.html

                http://msdn.microsoft.com/zh-cn/0b34tf65

                http://blog.sina.com.cn/s/blog_5fb3f1250100xodv.html           

文章出处:http://blog.sina.com.cn/u/2728844600
作者:天涯来客;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值