浙江省高等学校教师教育理论培训

微信搜索“毛凌志岗前心得”小程序

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C标准库——浮点数 - chenwu128 - 博客园

    C标准库——浮点数

    浮点数格式

    学C的时候就知道,浮点数采用的是类似于科学计数法的表示方式。具体的浮点数的模型是:

    一个尾数(mantissa),一个基数(base),一个指数(exponent)和符号位表示。

    再百度的深一点,在规范化形式下(没错,还有非规范形式),就可以把float和double的表示格式列个表格:

    类型
       

    存储位数
       

    偏移值

       

    符号位(s)
       

    指数位(e)
       

    尾数位(m)
       

    总位数
       

    十六进制
       

    十进制

    单精度 float
       

    1位
       

    8位
       

    23位
       

    32位
       

    0x7FH
       

    +127

    双精度 double
       

    1位
       

    11 位
       

    52位
       

    64位
       

    0x3FFH
       

    +1023

    不过有些细节是不得不说的:

    基数 ———— 这个基数是可以用户定义的,一般是2,但取10,16也是可以的。如何指定呢?

             在头文件float.h中定义了宏FLT—RADIX,它的值就是选定的基数。

    尾数 ———— 这是个定点小数,采用原码存储。尾数的最左端隐含了1,也就是说23位全部用来

             表示小数,而实际表示的数是24位精度。

    指数 ———— 这当然是整数,不过采用移码存储。为了处理负指数的情况,要把实际指数值加上

             一个偏移值作为保存值(float为127;double为1023)。对单精度浮点而言,有效的

             指数范围是 -126~127(保存值为1~254,这是因为两个端点值用作特殊值表示)。

    IEEE 754定义了什么

    只要一说到浮点数,这个标准是不能不提的。那么这个标准主要规定了哪些东西呢?

    A、浮点数的格式:

        除了上面提到的两种基本的浮点格式,还定义了这两种格式的扩展。

               但标准只规定扩展格式的最小精度和大小。例如,IEEE 双精度扩展格式必须至少具

               有64位有效数字,并总共占用至少79 位。

    

    B、4种浮点数舍入方式:

        舍入到最接近:将结果舍入为最接近且可以表示的值(默认)。这种方式下,采取的向偶数舍入,

        与我们熟悉的'四舍五入'不同。这主要是为了处理中值(两个相邻整数的平均值),如果这些值都遵循'五入',

        那么在数值计算中会累积较大误差。也就是说——— 0.5要舍到0,1.5要入到2 ———以保证50%的概率。

        朝+∞方向舍入:将结果朝正无限大(向上)的方向舍入。

        朝-∞方向舍入:将结果朝负无限大(向下)的方向舍入。

        朝0方向舍入:将结果朝0的方向舍入。忽略小数部分。

    这些舍入方式是可以由float.h中的宏FLT—ROUNDS指定的。

    

    C、5种浮点异常:

        无效运算: 默认返回NaN(如对负数开平方时)

        被零除:   默认返回负无穷或正无穷

        上溢: 默认返回正负无穷大(结果数据太大无法表示时)

        下溢: 默认返回非规范数(结果数据太小无法表示时)

        不准确: 默认返回舍入后的正确值

    如果产生异常,就会影响异常向量表,有些还会产生中断。至于中断,异常处理当然不是本文要讨论的。

    

    D、特殊值:(还记得指数部分没有用到的两个端点值么?)

        NaN(Not a Number):对于单精度浮点数,NaN 表示为指数为128(保存值=255),且尾数不等于零的浮点数。

        ± ∞: 这个数的定义和NaN一样,不过它的尾数一定为0.(用于大出范围的数)

        ± 0: 对单精度而言,0表示为指数域为-127(保存值=0),尾数域为全为0。

        非规范化数: 这个数的定义和有符号0一样,不过尾数不能为0.(用于小出范围的数)

    这个标准规范的东西当然不止这些,还有一些关于运算准确度要求、不同类型数据间转换及不同进制数据间的转换等等。

    其实这里谈到的是浮点数最老的标准,新标准应该也有几个了吧,最好的资料当然就是这些标准的文档,倘若有时间,仔细看看还是有好处的。



    库文件float.h

    最初很多处理器在硬件方面并不支持浮点运算,因为这会增加不少成本,不支持浮点运算,会使微处理器

    设计的复杂度减半。之所以需要浮点运算,是因为科学计算等一些高精度运算的需要的存在。

    float.h这个文件的构造当然是要遵循这个标准的,不过这个头文件并有太多的东西。除了前面提到过的两个宏,

    这个头文件还定义了一些关于浮点数取值范围的宏。

    

    其实也没有特别的理由要来认识这个库,毕竟即使是做数值计算的算法,也可以用MATLAB 这个彪悍的工具。

    不过,在了解了这个头文件后,约定整数范围的limits.h就很容易看清楚了。

    不过这也仅限于认识这个库,至于它要怎么实现就又是另一个层次的问题了。

    

    参考文章:定点数与浮点数的区别。(文章不错,虽然有些小错误)
    分类: C/C++

posted on 2012-10-08 07:57  lexus  阅读(313)  评论(0编辑  收藏  举报