V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
MonkLuf
V2EX  ›  问与答

float 类型的二进制编码方式为什么这样设计?

  •  
  •   MonkLuf · 2015-01-17 15:59:47 +08:00 · 2850 次点击
    这是一个创建于 3633 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在c/c++语言中,单精度浮点数float的二进制存储方式如下:

    1位符号位(S) + 8位指数位(E) + 23位尾数位(M)
    

    最后表示成十进制是:

    1. if E == 0 and M == 0: N=0
    2. if E == 0 and M != 0: N= ((-1)^S) * ( (2^(-126)) * 0.M )
    3. if E > 0 and E < 255 and M != 0: N= ((-1)^S) * ( (2^(E-127)) * 1.M)
    4. if E == 255: 特殊字符
    

    请教各位,为什么有了第3条规则还要第2条呢?

    阮一峰老师: http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html

    文章中说,第2条规则的存在原因:

    (2)E全为0。这时,浮点数的指数E等于1-127(或者1-1023),有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。

    但是±0用第三条规则照样可以表示啊?

    请指点~

    7 条回复    2015-01-18 00:08:15 +08:00
    kcworms
        1
    kcworms  
       2015-01-17 18:08:47 +08:00
    正负0怎么用第三条表示?小数点前应该总是有个1
    flyaway
        2
    flyaway  
       2015-01-17 18:10:27 +08:00
    可以找一本「计算机组成原理」的书来翻一下……至于为什么,这可能要追溯历史问题了……
    bcxx
        3
    bcxx  
       2015-01-17 18:52:39 +08:00
    因为真的是只有三种表示形式咯……

    实际值 V = (-1) ^ S * m * 2 ^ E

    1. 规范化的表示

    e = E + bias
    bias = 2^(k-1) - 1 (k 是指数 e 的长度)
    m = 1 + M

    2. 非规范化的(正负 0、0 附近的数)

    +0: s = 0, 其他位全部是 0
    - 0: s = 1, 其他位全部是 1

    或者有

    e = 1 - bias (那种非常接近 0 的数)


    3. NaN

    S = 0, E 全部是 1: +inf
    S = 1, E 全部是 1 : - inf
    SoloCompany
        4
    SoloCompany  
       2015-01-17 21:06:57 +08:00 via iPad
    同样 E = 0
    2 能表达的最小绝对值是 2 ^ -149
    3 能表达的最小值是 (1 + 2 ^ -23) * 2 ^ -127
    怎么个一样法?
    justjavac
        5
    justjavac  
       2015-01-17 23:06:23 +08:00
    - [代码之谜(四)- 浮点数(从惊讶到思考)](http://justjavac.com/codepuzzle/2012/11/02/codepuzzle-float-from-surprised-to-ponder.html)

    - [代码之谜(五)- 浮点数(谁偷了你的精度?)](http://justjavac.com/codepuzzle/2012/11/11/codepuzzle-float-who-stole-your-accuracy.html)
    justjavac
        6
    justjavac  
       2015-01-17 23:06:55 +08:00
    代码之谜(四)- 浮点数(从惊讶到思考)
    http://justjavac.com/codepuzzle/2012/11/02/codepuzzle-float-from-surprised-to-ponder.html

    代码之谜(五)- 浮点数(谁偷了你的精度?)
    http://justjavac.com/codepuzzle/2012/11/11/codepuzzle-float-who-stole-your-accuracy.html
    kaneg
        7
    kaneg  
       2015-01-18 00:08:15 +08:00 via iPhone
    应该是用最少的字节表示精度尽可能大的数字
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2623 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 07:32 · PVG 15:32 · LAX 23:32 · JFK 02:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.