为什么不使用基于二进制补码的浮点数?

Aba*_*han 1 floating-point precision

float64、32 和 16 的 IEEE 754 标准使用有符号有效数和有偏指数。作为一名设计硬件架构的学生,对有效数和指数部分使用二进制补码对我来说更有意义。

例如,32 位(半精度)浮点数被定义为第一位代表符号,接下来的 8 位 - 指数(127 偏置),最后 23 位代表尾数。要实现(负数的)加法/乘法,我们需要将尾数转换为二进制补码并返回。由此产生的硬件相当复杂。

相反,请考虑前 8 位是否表示指数,后 24 位表示尾数,两者均采用二进制补码。位移、加法和乘法相对简单,硬件也不那么复杂。此外,我们有一个唯一的有效位零(两个零表示有符号位)

我搜索了几个月来寻找这些设计决策的原因,并找到了这些:

  1. 2 的补码表示更难比较。

这是真的,我们需要一个加法器(减法器)来比较 2 的补码。但是,对于 GPU 和我自己的基于 FPGA 的 CNN 加速器等流水线架构,我们需要避免可变延迟。逐位迭代比较有符号表示使得无法预先确定延迟。在我看来,在这种情况下减法更好。

  1. 历史原因:处理 NAN 和 inf

也许我们可以为此分配一两个位。并将有效数设为 23 位。

  1. +0 和 -0 为零,这样 1/+0 = +inf 和 1/-0 = -inf

现在这是一个正当理由。它并不真正适用于我的用例,但我想知道如果他们用额外的位来实现它是否会更好。

我的用例

我正在 FPGA 上构建 CNN 加速器。预定义乘法和加法延迟以及最小化硬件复杂性对我来说至关重要。我不执行除法,也不必担心 inf 和 NAN。

因此,我决定使用如上所述的二进制补码表示来使用浮点的自定义内部表示。有什么明显的缺点我应该小心吗?

ali*_*ias 5

这是一个充分研究的话题,有正在使用2的补浮点表示系统; 通常是那些早于 IEEE-754 的,尽管最近的化身也可用。有关此类系统特性的研究,请参阅本文:https : //hal.archives-ouvertes.fr/hal-00157268/document

这是轶事,但 Kahan(IEEE754 标准的设计者)确实认为具有单独的 +/-0 对于浮点通常用于的近似很重要,如果浮点 0 结果本质上是正数,这一点很重要或消极。

所以,是的:完全有可能有 2 的补码浮点数;但标准选择的符号幅度表示。无论你选择哪一个,有些操作会很容易,有些会更难;对比是最明显的。当然,如果您正在设计自己的硬件,则没有什么能阻止您选择最适合您需求的表示!特别是,您甚至可以使用所谓的 unum 和 posit ,其中指数和有效数部分不是固定大小,而是取决于您在范围内的位置。见这里:https : //www.johndcook.com/blog/2018/04/11/anatomy-of-a-posit-number/


Chr*_*odd 3

2 补码用于整数运算的原因是,它允许将相同的硬件和指令用于有符号和无符号运算,仅在如何检测溢出方面存在微小差异。对于浮点,没有人关心“无符号”浮点,因此如果您在位级别实现它,那么使用 2 补码没有任何好处(节省)。我能看到使用 2s 补码优势的唯一方法是,如果您使用的硬件已经具有某种 2s 补码 ALU。

2s补码在其表示中存在严重的不对称问题(<0的可表示值多于>0),如果您尝试在任何需要舍入或潜在精度损失(例如浮点)的情况下使用它,则会导致各种数学稳定性问题-point 通常用于。