免责声明
这是试图提供一个易于理解的关于浮点编码如何工作的解释。这是一种简化,不涵盖真正的 IEEE 754 浮点标准的任何技术方面(归一化、有符号零、无穷大、NaN、舍入等)。但是,这里提出的想法是正确的。
由于计算机使用基数为2 的数字而人类不容易处理它们,这一事实严重阻碍了对浮点数如何工作的理解。我将尝试解释浮点数是如何使用 base 10 工作的。
让我们使用符号和基数 10 数字(即我们每天使用的从 0 到 9 的常用数字)构造一个浮点数表示。
假设我们有10 方形单元格,每个单元格可以包含符号(+ 或 -)或十进制数字(0、1、2、3、 4、5、6、7、8 或 9)。
我们可以使用 10 位数字来存储有符号整数。符号一位,数值九位:
sign -+ +-------- 9 decimal digits -----+
v v v
+---+---+---+---+---+---+---+---+---+---+
| + | 0 | 0 | 0 | 0 | 0 | 1 | 5 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+
这就是值1500 表示为整数的方式。
我们还可以使用它们来存储浮点数。例如,尾数为 7 位,指数为 3 位:
+------ sign digits --------+
v v
+---+---+---+---+---+---+---+---+---+---+
| + | 0 | 0 | 0 | 1 | 5 | 0 | + | 0 | 1 |
+---+---+---+---+---+---+---+---+---+---+
|<-------- Mantissa ------->|<-- Exp -->|
这是1500 作为浮点值的可能表示形式之一(使用我们的 10 位十进制数字表示)。
尾数(M)的值为+150,指数(E)的值为+1。上面表示的值为:
V = M * 10^E = 150 * 10^1 = 1500
范围
整数表示可以存储-(10^9-1) (-999,999,999) 和+(10^9-1) (+999,999,999) 之间的有符号值。此外,它可以表示这些限制之间的每一个整数值。更重要的是,每个值都有一个表示形式,而且是精确的。
浮点表示可以存储 -999,999 和 +999,999 之间的尾数 (M) 和 -99 和 +99 之间的指数 (E) 的有符号值。
它可以存储-999,999*10^99 和+999,999*10^99 之间的值。这些数字有105 数字,比上面表示为整数的最大数字的9 数字多得多。
精度的松散
请注意,对于整数值,M 存储符号和值的前 6 位(或更少),E 是不适合 M 的位数。
V = M * 10^E
让我们尝试使用我们的浮点编码来表示V = +987,654,321。
因为M 仅限于+999,999,所以它只能存储+987,654,而E 将是+3(V 的最后 3 位数字不能放入 M)。
把它们放在一起:
+987,654 * 10^(+3) = +987,654,000
这不是 V 的原始值,而是我们可以使用此表示获得的最佳近似值。
请注意,+987,654,000 和+987,654,999 之间(包括在内)的所有数字都使用相同的值(M=+987,654, E=+3)进行近似。此外,对于大于 +999,999 的数字,也无法存储十进制数字。
作为一般规则,对于大于 M (+999.999) 最大值的数字,此方法为 +999,999*10^E 和 +999,999*10^(E+1)-1 之间的所有值生成相同的表示形式(整数或实数,它不会没关系)。
结论
对于较大的值(大于M 的最大值),浮点表示在它可以表示的数字之间存在间隙。随着E 值的增加,这些差距越来越大。
“浮点”的整个想法是存储十几个最具代表性的数字(数字的开头)和数字的大小。
我们以光速为例。它的值约为300,000 km/s。如此庞大,对于大多数实际用途而言,您根本不在乎它是 300,000.001 km/s 还是 300,000.326 km/s。
其实也没那么大,更好的近似是299,792.458 km/s。
浮点数提取光速的重要特征:其量级为数十万公里/秒(E=5),其值为3(数十万公里/秒)。
speed of light = 3*10^5 km/s
我们的浮点表示可以近似为:299,792 km/s (M=299,792, E=0)。