为什么定点缩放因子往往是 2 的幂?

问题描述

假设我们有两个浮点值:1.234.56。 要在没有浮点支持的机器中表示和添加这些,我们将不得不回退到定点表示。

所以我们选择100作为比例因子,只是为了去掉小数点:

1 - 通过比例因子将它们相乘 => 123456

2 - 添加它们 123 + 456 = 579

3- 除以相同的比例因子 => 5.79

等于浮点加1.23 + 4.56 = 5.79

现在,为什么我继续阅读在线文章,其中缩放因子往往是 2 的幂?

https://en.wikipedia.org/wiki/Scale_factor_(computer_science)

https://www.allaboutcircuits.com/technical-articles/fixed-point-representation-the-q-format-and-addition-examples/

如果我选择说 2^5 = 32 作为我的缩放因子,那么我们有:

-> 1.23 * 32 = 39.36 ~= 39
-> 4.56 * 32 = 145.92 ~= 145
-> 39 + 149 = 188 
-> 188 / 32 = 5.87

5.87输出甚至不精确。那么为什么我们选择 2 的幂呢? 为什么我们不直接选择 10 的幂作为因数?

编辑

我也看到过这样的帖子: https://spin.atomicobject.com/2012/03/15/simple-fixed-point-math/

选择 2 的幂是因为计算机可以快速表示它们,即 2^16 可以通过位移来完成: 1 << 16,但是 10 的幂不能计算得那么快。

是吗?我们基本上会因为一点延迟(如果有的话)而破坏精度?

解决方法

等于浮点数加1.23 + 4.56 = 5.79

不完全。

1.23、4.56、5.79 作为源代码是完全可以表示的。作为用 binary64 编码的浮点数,它们不是。就像 0.3333 不完全是三分之一一样,IEE-754 二进制使用附近的值 - 在 253 的 1 部分之内。因此,相加可能提供预期的总和,或者可能出现非常接近的其他总和。

为什么我一直在阅读在线文章,其中缩放因子往往是 2 的幂?

使用二进制浮点数,按 2 的幂进行缩放不会注入精度损失。该产品与其预先标定的值完全一样。

为什么我们不选择 10 的幂作为因数?

按 10 的幂进行缩放在纸面上效果很好(经典数学),但对于二进制浮点,乘积可能不精确,而是使用了四舍五入的值。因此,我们的缩放会注入一个错误。

是吗?我们基本上会因为一点延迟(如果有的话)而破坏精度?

不,还有更多问题。由于存在如此多的问题并且速度很重要,因此浮点硬件制造商需要一个非常具体的 IEEE-754。即使在 40 年后,也会出现极端情况。在过去的 20 年里,IEEE-754 的十进制 版本也存在。整个规范的那部分正在缓慢地在硬件中实现,而不是 slooooow 软件十进制浮点实现。在市场推动更广泛的接受之前,二进制浮点与经典数学 (1.23 + 4.56) 之间的差异将继续占据主导地位,而不是转换为十进制浮点。