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的表示格式。

- float格式中,s、exp、和frac字段分别为1位、k=8位和n=23位,得到一个32位的表示。
- double格式中,s、exp、和frac字段分别为1位、k=11位和n=52位,得到一个64的表示。
给定了位表示,根据exp的值,被编码的值可以分成三种不同的情况。

情况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 被解释为描述小数值 f , 0 ≤ 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 |
