Advertisement

IEEE 浮点表示

阅读量:

计算机中浮点数的表示方法采用该标准——IEEE浮点表示

    • 基本概念

      • 情况1:常规值
      • 情况2:非常规的值
      • 情况3:特殊值
    • 表示方法

      • 示例1
        • 示例分析
      • 非常规情况

      • 常规情况

      • 剩下特殊情况,不表述

      • 示例2

        • 小数是0
    • 小数不是0

    • 扩展

    • 舍入

基本概念

形如x * 2y这样的数,可以通过给定 x 和 y 的值来表示。
IEEE 浮点标准用 V = (-1)^s * M * 2^E 的形式来表示一个数:

  • 符号(sign) s 决定这个数是正数还是负数(s=0正数,s=1负数)。
  • 尾数(significand)M 是一个二进制小数。
  • 阶码(exponent)E 的作用是对浮点数加权,权重是2的E次幂。

下图分别表示(C语言中)单精度浮点float 和双精度浮点 double的表示格式。
C语言浮点数表示

  • float格式中,s、exp、和frac字段分别为1位、k=8位和n=23位,得到一个32位的表示。
  • double格式中,s、exp、和frac字段分别为1位、k=11位和n=52位,得到一个64的表示。

给定了位表示,根据exp的值,被编码的值可以分成三种不同的情况。
C语言浮点数表示

情况1:常规值

也就是最普遍的情况。 exp 的位模式不全是0,也不全是1(单精度数值为255,双精度值为2047)。阶码的值为 E =e - Bias
e 是无符号数,位表示为: e k-1 … e1e0 因此它的值在 1 ~ 254 之间(单精度),1~2046之间(双精度);
Bias 是偏置值:等于 2 k-1 - 1 (单精度是127,双精度是1023)
因此,E 的值就可以得到一个范围(包含边界): -126 ~ 127(单精度),-1022 ~ 1023(双精度)
小数字段 frac 被解释为描述小数值 f0 ≤ f ≤ 1
二进制表示为 0.f n-1 … f1f0
由此尾数被定义为 M = 1 + f (也叫做隐含的以1开头的表示)

情况2:非常规的值

当阶码全都为0时,所表示的数是非规格化的形式。
阶码值是 E = 1 - Bias
尾数值是 M = f ,也就是小数字段的值,不包含隐含的1。

情况3:特殊值

当阶码位全为1时,表示特殊值。

  • 无穷大:阶码位全为1,小数位全为0
  • NaN:表示不是一个数(Not a Number),即阶码位全为1,小数位不全为0。

表示方法

示例1

以一个6位二进制为固定长度的范围。来表示一些数,这样方便我们更好的理解。假定s、exp、frac字段分别为 1位,3位,和2位。
这样我们得到一个6位二进制表示法:s=1,k=3,n=2 ,我们以此来表示一些数。

示例分析

在表示数之前,我们先来分析一下这个6位的二进制。
由阶码k 的位分布情况,能得到常规值,和非常规值。他们是平滑过渡的。
先确定偏置量 Bias = 2k-1 - 1 = 3 (k=3)
下面我们来了解他们能表示的数的范围和值。不考虑符号位。
公式:V = (-1)^0 * M * 2^E
请考虑下面的二进制位,符号位的值固定为1,下面的计算都会省略

非常规情况

E = 1 - Bias = -2
M = f
[------] 0 000 00 (最小值的二进制位分布)
V = 0 * 0= \dfrac{0}{16}
[------] 0 000 01
V=\dfrac{1}{4} * \dfrac{1}{4}=\dfrac{1}{16}
[------] 0 000 10
V=\dfrac{2}{4} * \dfrac{1}{4}=\dfrac{2}{16}
[------] 0 000 11 (最大值的二进制位分布)
V= \dfrac{3}{4} * \dfrac{1}{4} = \dfrac{3}{16}

常规情况

E = e - Bias
M = 1 + f
[------] 0 001 00 (最小值二进制位分布)
V=(1+0) * 2^{1 - 3} = \dfrac{4}{4} * \dfrac{1}{4} = \dfrac{4}{16}
[------] 0 001 01
V=(1+\dfrac{1}{4}) * 2^{1-3}=\dfrac{5}{4} * \dfrac{1}{4}=\dfrac{5}{16}
后面的省略了…你可以自行转换计算

[------] 0 110 11 (最大值二进制位分布)
V=(1+\dfrac{3}{4}) * 2^{6-3}=\dfrac{7}{4}*8=14*\dfrac{16}{16}=\dfrac{224}{16}

剩下特殊情况,不表述

示例2

进一步理解浮点数,将如下数转换为二进制表示。(6位二进制位)

小数是0
  • [十进制] 8.0
    8的二进制为:1000
    可以写成 1.000*2^3
    E = 3 = e - 3;得到 e = 6; 阶码表示为110,加上符号位和小数位。得到:0 110 00

  • [十进制] 4.0
    4转换成2进制位:100;将小数点移到二进制位1的右边, 可以得到1.00* 2^2 ,E = 2 = e - 3;e = 5;
    再将5写作二进制表示:101
    加上符号和小数位写作:0 101 00

小数不是0
  • [十进制] 0.25
    没有整数部分,将小数部分转化成二进制位。
    0.25 * 2 = 0.5---取到第一位二进制位 0
    0.5 * 2 =1.0---取到最后一位二进制位 1
    写作二进制位:0.01
    改写成:1.0 * 2^{-2}
    得到 E = -2 = e - 3;e = 1 。阶码部分为:001,小数位都已经转化为0,加上符号位0
    得到二进制位:000100

  • [十进制] 2.25
    2 写成二进制位:10
    尾数位 f 表示如下,通过乘以2直到值为1来得到小数的二进制位:
    0.25 * 2 = 0.5 --- 整数部分是---0
    0.5 * 2 = 1.0 ---整数部分是---1 小数部分为0了,结束。
    写作尾数位:01
    2.25写作二进制位表示:10.01
    可以写成:1.001 * 2^1
    E = 1 = e-3;e=4
    阶码位表示为:100
    加上符号位和小数位:0100001
    如上,我们发现,7位二进制位才能表示2.25。因为小数位需要3位二进制位来表示。

扩展

浮点标准能精确的表示任意一个数吗?比如 0.1
尝试将0.1转化为二进制位表示:
0.1 * 2 = 0.2---0
0.2 * 2 = 0.4---0
0.4 * 2 = 0.8---0
0.8 * 2=1.6---1
0.6 * 2=1.2---1
0.2 * 2=0.4---0
0.4 * 2=0.8---0
0.8 * 2=1.6---1
0.6 * 2=1.2---1

我们发现除了第一个0,已经出现了循环位0011
00011...0011
由此看出0.1并非精确值,而是近似值。位越多,越趋近值0.1。

舍入

浮点数的舍入方式有向整数舍入,向零舍入,向上和向下舍入。
下面以取整数为例:

示例值 1.4 1.6 1.5 2.5 -1.4 -1.5 -2.5
向整数舍入 1 2 2 2 -1 -2 -2
向零舍入 1 1 1 2 -1 -1 -2
向上舍入 2 2 2 3 -1 -1 -2
向下舍入 1 1 1 2 -2 -2 -3

全部评论 (0)

还没有任何评论哟~