设为首页收藏本站
查看: 424|回复: 3

浮点数的存储格式

[复制链接]
  • TA的每日心情
    无聊
    2019-4-8 21:46
  • 签到天数: 34 天

    [LV.5]常住居民I

    发表于 2019-1-12 20:46:14 | 显示全部楼层 |阅读模式
            IEEE754标准采用类似于科学记数法的方法存储浮点数,将浮点数存储为二进制定点小数(即尾数)乘以2的整数次幂的形式。

    整体呈现
    •float(单精度浮点型)
    float占用4个字节(32位),其中符号位(sign)占1位,指数位(exponent)占8位,尾数位(mantissa)占23位。


    •double(双精度浮点型)
    double占用8个字节(64位),其中数值符号位(sign)占1位,指数位(exponent)占11位,尾数位(mantissa)占52位。


    符号位
            符号位表示浮点数的正负,0表示正,1表示负。

    指数位
            指数又称阶码,阶码指明了小数点在数据中的位置。指数必须是有符号数才能表达很大或很小的数值,但是有符号数通常的表示法——补码,将会使电路设计变得复杂,使比较变得困难。为了解决这一问题,计算机将实际指数加上一个偏移量作为浮点数的阶码, 将其调整到一个无符号数的范围内以便进行比较,也就是说实际指数等于阶码减去偏移量。若浮点数有n位指数位,则偏移量=2^(n-1)-1,阶码范围为[0,2^(n)-1](0和2^(n)-1具有特殊用途,不遵守一般的指数修正规则,稍后再做解释)。
    例如,float的指数偏移量为+127,阶码范围为[0,255],实际指数的范围为-126~127;double的指数偏移量为+1023,阶码范围为[0,2047],实际指数范围为-1022~1023。

    尾数位
    •规约形式的浮点数
            阶码在0<e<2^(n)-1内的浮点数被称为规约形式的浮点数,规约形式的浮点数的尾数位之前隐含了一位1(1.111...),因此实际上float和double的尾数位数分别为24和53,该形式的浮点数的尾数是一个[1,2)范围内的数,如规约形式的float的尾数范围为[1,2-2^(-23))。
    •非规约形式的浮点数
            若一浮点数的阶码为0,尾数不为0,那么该浮点数被称为非规约形式的浮点数。除了一般浮点数,IEEE754-1985标准采用非规约浮点数来解决填补绝对值意义下最小规约数与零的距离。IEEE 754标准规定:非规约形式的浮点数的指数偏移量比规约形式的浮点数小1。例如,最小的规约形式的单精度浮点数的阶码为1,实际指数为-126;而非规约形式的单精度浮点数的阶码为0,对应的实际指数也是-126而不是-127。非规约形式的浮点数的尾数位之前隐含了一位0(0.111...),该形式的浮点数的尾数的是一个(0,1)范围内的数,如非规约形式的float的尾数范围为(0,1-2^(-23))。

    特殊值
    若阶码为0,尾数为0,则表示±0(与符号位有关);
    若阶码为2^n-1,且尾数为0,则表示±无穷大(inf,infinity);
    若阶码为2^n-1,且尾数非0,则表示非数值(NaN,Not a Number), NaN 用于处理计算中出现的错误情况,比如 0.0 除以 0.0 或者求负数的平方根。

            下面举一个例子,以此帮助大家更好地理解和消化以上概念:
    以3.75为例,首先将其转换为二进制形式11.11,然后向右移动1位变为1.111(尾数规约化),尾数的最高有效位缺省,不占据存储空间,相应地,尾数每右移1位,指数就要增1,这里的指数为1。最后将指数加上与类型相关的偏移量作为阶码,假设数据类型是float,那么最后的阶码就等于128(1+127)。


    舍入处理
    实际上,只有分子为整数,分母为2的整数次幂的数能完全地转换为二进制形式,例如3.75,其他小数并不能完全地转换为二进制小数,例如0.2的二进制形式为0.001100110011001100110011001100110011001100110011001101...,小数点后有数不净的数,而浮点型的尾数位有限,故将尾数规约化后还要对数值进行舍入处理。
    IEEE 754标准提供了四种可选方法:
    1.        就近舍入。若超出部分大于最低有效位权值的一半,则进1;若超出部分小于最低有效位权值的一半则舍去;若超出部分等于最低有效位权值的一半,若最低位为0,则舍去,否则进1(凑偶);
    2.        朝0舍入。即朝数轴原点方向舍入,就是简单的截尾。无论尾数是正数还是负数,截尾都使取值的绝对值比原值的绝对值小。这种方法容易导致误差积累。
    3.        朝+∞舍入。对正数来说,只要多余位不为0就进1;对负数来说,则是简单的截尾。
    4.        朝-∞舍入。处理方法与朝+∞舍入相反。  

    VS采用的是第一种方法,我们可以通过下面的方法验证:
    根据以上规定,舍入处理后的0.2的二进制形式为0.00110011001100110011001101,转换为十进制等于0.20000000298023224。


    若VS对浮点数采用的舍入方法是就近舍入,则输出的结果也应该是0.20000000298023224。经过验证,结果符合我们的预期。


    经过多次类似于这样的验证,可以确定VS采用的正是就近舍入方法。

    C头文件float.h
            float.h提供了与浮点型大小限制相关的详细信息。该头文件定义了一系列供实现使用的明示常量.float.h头文件包含以下类似的代码:

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    评分

    2

    查看全部评分

  • TA的每日心情
    擦汗
    6 天前
  • 签到天数: 120 天

    [LV.7]常住居民III

    发表于 2019-1-12 20:48:38 | 显示全部楼层
    感谢楼主分享,学习了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    5 天前
  • 签到天数: 361 天

    [LV.8]以坛为家I

    发表于 2019-1-12 21:48:40 | 显示全部楼层
    这些内容我一直都搞不清楚
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-3-11 11:39
  • 签到天数: 145 天

    [LV.7]常住居民III

    发表于 2019-1-12 22:38:16 | 显示全部楼层
    谢谢楼主分享。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    站长推荐 上一条 /1 下一条

    红盟社区--中国红客联盟 

    Processed in 0.086512 second(s), 19 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    Powered by HUC © 2001-2017 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表