C标准库——浮点数

浮点数格式

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

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

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

类型

存储位数

偏移值


符号位(s)

指数位(e)

尾数位(m)

总位数

十六进制

十进制

单精度 float

1

8

23

32

0x7FH

+127

双精度 double

1

11

52

64

0x3FFH

+1023


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

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

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

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

指数 ———— 这当然是整数,不过采用移码存储。为了处理负指数的情况,要把实际指数值加上一个偏移值作为保存值(float127;double1023)。对单精度浮点而言,有效的指数范围是 -126~127(保存值为1~254,这是因为两个端点值用作特殊值表示)。


IEEE 754定义了什么

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

A浮点数的格式:

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

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

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

 

B4种浮点数舍入方式:

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

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

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

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

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

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

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

 

C5种浮点异常

  • 无效运算: 默认返回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就很容易看清楚了。不过这也仅限于认识这个库,至于它要怎么实现就又是另一个层次的问题了。

 

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

posted @ 2012-10-07 15:38  陈小硕  阅读(4992)  评论(1编辑  收藏  举报