background image

C

C

C

语言浮点数运算

有些 语言书上说 float 型的有效位数是 6~7 位,为什么不是 位或者 位?而是一个

变化的 6~7 位?

浮点数在内存中是如何存放的?

float 浮点数要比同为 字节的 int 定点数表示的范围大的多,那么是否可以使用浮点数

替代定点数?

为什么 float 型浮点数 9.87654321 > 9.87654322 不成立?为何 10.2 - 9 的结果不是 1.2

而是 1.1999998?为何 987654321 + 987.654322 的结果不是 987655308.654322

如何才能精确比较浮点数真实的大小?

看完本文档,你将会得到答案!

在论坛上或 QQ 群中有时会看到新同学问一些有关浮点数运算的问题,经常是走了错误

的方向,但苦于交流方式不方便,无法为其详细说明,在此,我将我所掌握的一些知识加以
整理写出来,希望对大家能有所帮助。更多案例请访问我的博客 blog.sina.com.cn/ifreecoding。

我主要是从事底层软件开发的,最开始写驱动程序,后来也做一些简单的业务层软件,

在我所涉及的工作范围内,我使用的都是定点数,而且 90%以上都是无符号定点数,在我
印象中并没有使用过浮点数,即使做过一个专门使用 DSP 来处理信号的项目,也只是使用
了无符号定点数,我将在另一篇案例《C 语言使用定点数代替浮点数计算》里介绍定点数处
理简单的浮点数的方法,这也是在底层驱动中常使用的方法。

C

C

C

语言浮点数

C 语言标准 C89 里规定了 3 种浮点数,float 型、double 型和 long double 型,其中 float

型占 4 个字节,double 型占 8 个字节,long double 型长度要大于等于 double 型,本文档将
以 float 型为例进行介绍,double 型和 long double 型只是比 float 型位数长,原理都是一样的。

float 型可以表示的范围是-3.402823466e

38

~3.402823466e

38

,而作为同为 4 个字节的定点

数却只能表示-2147483648~2147483647 的范围,使用同样的内存空间,浮点数却能比定点
数表示大得多的范围,这是不是太神奇了?既然浮点数能表示这么大的范围,那么我们为何
不使用浮点数来代替定点数呢?

先不说浮点数实现起来比较复杂,有些处理器还专门配置了硬件浮点运算单元用于浮点

运算,主要原因是浮点数根本就无法取代定点数,因为精度问题。鱼和熊掌不可兼得,浮点

数表示了非常大的范围,但它失去了非常准的精度。在说明精度问题前,我们先了解一下浮

点数的格式。

ANSI/IEEE

ANSI/IEEE

ANSI/IEEE

ANSI/IEEE Std

Std

Std

Std 754-1985

754-1985

754-1985

754-1985 标准

IEEE 754 是最广泛使用的二进制浮点数算术标准,被许多 CPU 与浮点运算器所采用。

IEEE 754 规定了多种表示浮点数值的方式,在本文档里只介绍 32bits 的 float 浮点类型。它
被分为 3 个部分,分别是符号位 S(sign bit)、指数偏差 E(exponent bias)和小数部分 F
(fraction)。