本次笔记内容:
04.浮点数的计算机表示
IEEE的浮点数标准
IEEE的754标准
在1985年建立,如下表。
2^i | 2^{i-1} | … | 4 | 2 | 1 | |||||
---|---|---|---|---|---|---|---|---|---|---|
b_i | b_{i-1} | … | b_2 | b_1 | b_0 | b_{-1} | b_{-2} | b_{-3} | … | b_{-j} |
1/2 | 1/4 | 1/8 | … | 2^{-j} |
可以看出,其二进制表示方式为 ∑ k = − j i b k ⋅ 2 k \sum^i_{k=-j} b_k \cdot 2^k ∑k=−jibk⋅2k。
浮点数示例
下例中,“-”代表又。
- 5-3/4:101.11_2
- 2-7/8:10.111_2
- 63/64:0.111111_2
可以看出,存在局限性:
只能精确地表示X/2^k这类形式的数据,而对于下列数据,不能精确表示:
- 1/3:0.0101010101[01]…_2
- 1/5:0.001100110011[0011]…_2
- 1/10:0.0001100110011[0011]…_2
计算机中浮点数二进制表示
数字形式: ( − 1 ) s M 2 E (-1)^s M 2^E (−1)sM2E
- 符号:s
- 尾数:M,是一个位于区间[1.0, 2.0)内的小数
- 阶码:E
编码形式:
s | exp | frac |
---|
exp域:E(注意,E要进行变换,再存储在exp中);
frac域:M。
- 单精度浮点数:exp域宽度为8bits,frac域宽度为23bits,总共32bits;
- 双精度浮点数:exp域宽度为11bits,frac域宽度为52bits,总共64bits;
- 扩展精度浮点数:exp域宽度为15bits,frac域宽度为63bits,总共80bits。(1 bit wasted)
浮点数的类型
- 规格化浮点数
- 非规格化浮点数
- 一些特殊值
规格化浮点数(Normalized)
- 满足条件:exp不全为0且不全为1。
- 真实的阶码值需要减去一个偏置(biased)量:
-
- E = Exp - Bias
-
- Exp:exp域所表示的无符号数值
-
- Bias的取值:
-
-
- 单精度数:127(Exp:1…254,E:-126…127)
-
-
-
- 双精度数:1023(Exp:1…2046,E:-1022…1023)
-
-
-
- Bias = 2^{e-1} - 1,e = exp的域的位数
-
- frac的第一位隐含1:M = 1.xxx…x_2
-
- 因此第一位的“1”可以省去,xxx…x:bits of frac
-
- Minimum when 000…0 (M = 1.0)
-
- Maximum when 111…1 (M = 2.0 - \epsilon)
规格化浮点数示例
Float F = 15213.0;
// 二进制
15213_10 = 11101101101101_2
// 二进制向右移13位,再乘2^13
1.1101101101101_2 * 2^13
// 则其尾数为
M = 1.1101101101101_2
// 取小数部分,在计算机中存储为
frac = 11011011011010000000000
// 其阶码为
E = 13
Bias = 127
// 阶码在计算机中存储为,加上偏置量
Exp = 140 = 10001100
最终,15213.0在计算机中的存储为(第二行):
Hex | 4 | 6 | 6 | D | B | 4 | 0 | 0 |
---|---|---|---|---|---|---|---|---|
Binary | 0100 | 0110 | 0110 | 1101 | 1011 | 0100 | 0000 | 0000 |
140 | _100 | 0110 | 0____ | |||||
15213 | (1)110 | 1101 | 1011 | 01__ |
上表中,M取值一定位1.x,因此15213行的首个1省略。
非规格化浮点数(Denormalized)
- 满足条件:exp全为0。
- 其他域的取值
-
- E = -Bias + 1;
-
- M = 0.xxx…x_2
-
- xxx…x:bits of frac
为什么Bias取2^{e-1} - 1(e = exp的域的位数)?或者说,为什么在规格化浮点数情况下不允许exp取全0?
答:在不考虑符号位的情况下,考虑规格化浮点数的最小取值:首先E应该取1(exp为1减去偏移量即1-Bias),frac取1.0…。如果有数字,比这个数还小一点点,则只能将frac小数点再左移。此时,则需要exp全0这种表达,表示此时frac是0.开头,而非1.开头。0.开头即非规格化浮点数。
非规格化浮点数示例
- exp = 000…0,frac = 000…0
-
- 表示0,注意有+0与-0(由s位决定)。
- exp = 000…0,frac不等于0
-
- 表示“非常接近”于0的浮点数;
-
- 会逐步丧失经度,称为“Gradual underflow”。
一些特殊值
- 满足条件:exp全为1。
一些特殊值具体示例
- exp = 111…1,frac = 000…0
-
- 表示无穷,可用于表示数值的溢出
-
- 有正无穷与负无穷之分:1.0 / 0.0 = +∞;-1.0 / 0.0 = -∞
- exp = 111…1,frac 不等于全0
-
- Not-a-Number(NaN)
-
- E. g. sqrt(-1), ∞ - ∞, ∞ * 0
各种浮点数类型在数轴上的相对位置
NaN | -∞ | -Normalized | -Denorm | -0 | +0 | +Denorm | +Normalized | +∞ | NaN |
---|
实例:一种“小”浮点数
- 8位浮点数表示:exp域宽度为4 bits,frac域宽度为3 bits。则,其偏置量的值为2^(4-1) - 1 = 7.
- 其他规则符合IEEE 754规范。
取值范围如下表。
s | exp | frac | E | value |
---|---|---|---|---|
0 | 0000 | 000 | -6 | 0 |
0 | 0000 | 001 | -6 | 1/8 * 1/64 = 1/512 |
0 | 0000 | 010 | -6 | 2/8 * 1/64 = 2/512 |
… | ||||
0 | 0000 | 110 | -6 | 6/8 * 1/64 = 6/512 |
0 | 0000 | 111 | -6 | 7/8 * 1/64 = 7/512 |
0 | 0001 | 000 | -6 | 8/8 * 1/64 = 8/512 |
0 | 0001 | 001 | -6 | 9/8 * 1/64 = 9/512 |
… | ||||
0 | 0110 | 110 | -1 | 14/8 * 1/2 = 14/16 |
0 | 0110 | 111 | -1 |