计算机中浮点数的表示方法


IEEE 754标准

在C/C++等编程语言中,浮点数在计算机中的表示采用的是IEEE 754标准。该标准一共的规定了四种表示浮点数值的方式,其中常见的表示方式有两种:单精确度(32位)和双精确度(64位)。这两种表示方式在C/C++语言中分别可以用floatdouble关键字来定义。

单精度浮点数的表示方法

单精度浮点数的表示方法其实就是把一个32位分成了三个部分:

  1. 第一个部分,占1位,表示浮点数的符号,英文Sign,简称为S。
  2. 第二个部分,占8位,表示浮点数的指数,英文Exponent,简称为E。
  3. 第三个部分,占23位,表示浮点数的尾数,英文Mantissa,简称为M。

如下图所示:

 31         22                    0
+----------------------------------+
|S|EEEEEEEE|MMMMMMMMMMMMMMMMMMMMMMM|
+----------------------------------+
   30     23

对应浮点数表示的值为:

结合上面的公式,来理解各个部分的意义就更容易了:

  1. 符号部分,$(-1)^S$

    当S为0时,$(-1)^0 = 1$,表示浮点数的值大于0;同理,当S为1时,$(-1)^1 = -1$,表示浮点数的值小于0。

  2. 指数部分,$2^{(E-127)}$

    首先要明白:对于任何一个正实数x,都可以找到一个整数n,使得$2^n <= x < 2^{n+1}$。举个例子,比如5,可以找到n=2,使得$2^2 <= 5 < 2^3$,即$4 <= 5 < 8$。浮点数中的指数部分就是这里的n。

    那么为什么还要减去127呢?因为当浮点数值的绝对值小于1时,指数部分其实是小于0的。举个例子,比如0.45,只有$n=-2$时,使得$2^{-2} <= 0.45 < 2^{-1}$,即$0.25 <= 0.45 < 0.5$。而浮点数中指数部分占8位,可以表示范围[0-$2^8$),即[0-256),为了在指数部分能够表示负数,IEEE 754规定减去127,即$n = E - 127$。所以,如果浮点数的$n=-2$,那么实际的E应该是125。

  3. 尾数部分,$(1 + \frac{M}{2^{23}})$

    尾数部分占23位,可以表示范围[0-$2^{23}$),即[0-8388608)。

    可以这样理解尾数部分:把一条线分成8388608个段,也就是把$2^n$到$2^{n+1}$分成8388608个线段。尾数部分的值M,表示从$2^n$到浮点数值的绝对值x所要经过的线段数量,也就是$2^n$到x的长度占$2^n$到$2^{n+1}$长度的比例是多少。这个比例的值就是尾数部分公式中$\frac{M}{2^{23}}$的来由,而加1则表示线段的起点$2^n$的值。

单精度浮点数举例

有了上面的说明,再结合例子来理解一下,比如浮点数3.14:

  1. 符号部分

    因为3.14大于0,所以$S = 0$。

  2. 指数部分

    $2^1 <= 3.14 < 2^2$,所以$n=1$,那么$E = n + 127 = 128$。

  3. 尾数部分

    $2^1$到3.14的长度占$2^1$到$2^2$长度的比例是$\frac{(3.14 - 2^1)}{(2^2 - 2^1)} = 0.57$

总线段数量为$2^{23}$,那么,从$2^1$到3.14所要经过的线段数量$M = 0.57 * 2^{23} = 4781506.56$,四舍五入,转换成整数结果为$M = 4781507$。因为有四舍五入,所以浮点数保存的数据和实际数据是有误差的。

把S、E、M转换成二进制,就可以得到3.14的二进制表示0x4048f5c3

 S     E             M
+----------------------------------+
|0|10000000|10010001111010111000011|
+----------------------------------+

最后代入浮点数公式计算:

也可以使用IEEE-754浮点数转换工具来分析浮点数的表示方法。

双精度浮点数的表示方法

双精度浮点数和单精度浮点数的原理是一样的,只是各个部分长度不同而已。

双精度浮点数的表示方法其实就是把一个64位分成了三个部分:

  1. 第一个部分,占1位,表示浮点数的符号,英文Sign,简称为S。
  2. 第二个部分,占11位,表示浮点数的指数,英文Exponent,简称为E。
  3. 第三个部分,占52位,表示浮点数的尾数,英文Mantissa,简称为M。

对应浮点数表示的值为:


文章作者: Kiba Amor
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 Kiba Amor !
  目录