尽管对浮点格式的工作原理有相当好的了解,但我在完成问题时遇到了麻烦。有人可以引导我完成获得答案所需的步骤吗?为什么不可能完全表示 1/3,我们怎么知道我们已经得到了最接近 1/3 的数字?
2 回答
IEEE 754 中浮点数的小数部分由 2 的负幂之和构成。
例如, 0.5 是 2 -1, 0.75 是 2 -1 +2 -2等等......
为了帮助您的工作,请考虑
什么数通过将N 位2 的负幂相加接近 1/3 ?
并且 1/3 是无限的,在有限的位数 (32) 浮点数内不能恰好有 1/3
要完成这个问题,您可以实现一个相当简单的算法来达到接近 1/3 的值
N = 23 // mantissa bits
T = 1/3 // target
p = 0.5 // first negative power of 2
r = 0.0 // resultat
do N times
if ( r + p <= T ) r = r + p // add power of 2 if result is not bigger than target
p = p / 2 // next power of 2
done
要以二进制形式可视化结果,您可以在将p添加到r时打印“1”,如果不是,则打印“0”。最后一位可能是“1”,以使结果更接近目标。
回答“我们能走多远?” 浮点数的问题,将有效数(小数部分)更改为整数通常很有用。为此,请从普通 32 位二进制 IEEE 浮点数的惯用浮点格式开始:
- 符号 s(0 或 1 表示 + 或 -)、指数 e 和以“1”开头的分数 f。小数点后有 23 位。这三个部分组合起来表示数字 (–1) s •2 e •f。
然后缩放格式,使分数 f 改为整数 F。为此,我们从指数中减去 23 并将分数 f 乘以 2 23。然后我们有这种格式:
- 符号 s、指数 e–23 和等于 2 23 •f 的整数 F(因此 2 23 ≤ F < 2 24)。这些部分组合起来表示数字 (–1) s •2 e–23 •F = (–1) s •2 e •f。
现在,计算出 1/3 在习惯格式中的指数。要使 f 以“1.”开头,e 必须为 -2。我们可以从 1/3 = 2 –2 •4/3 和 1 ≤ 4/3 < 2的事实中看出这一点,因此,在二进制中,4/3 以“1.”开头。
然后,考虑缩放格式。在这种格式中,我们必须有: 符号 s 是 0,指数是 –2–23 = –25,并且 F 是某个整数,使得 (–1) 0 •2 –25 •F ≈ 1/3。
这很容易解决,F ≈ 2 25 •1/3 = 33554432/3 = 11184810.666…。与该值最接近的整数是 11184811,因此 F = 11184811。
现在我们可以看到 F 中的误差是 1/3(F 必须是整数与我们希望的值之间的差),并且该误差按比例缩放 2 -25,因此误差为 2 -25 /3 ≈ 9.934e-09。该值本身为 2 –25 •11184811,约为 0.3333333433。
(请注意,我只处理了普通数字。对于接近浮点格式限制的数字,还必须考虑上溢和下溢。)