首页 > 解决方案 > 为什么不使用基于二进制补码的浮点数?

问题描述

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 加速器。为乘法和加法预先定义延迟并最大限度地降低硬件复杂性对我来说至关重要。我不执行除法,也不必担心 infs 和 NAN。

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

标签: floating-pointprecision

解决方案


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

Kahan 本人(IEEE754 标准的设计者)确实认为,具有单独的 +/-0 对于浮点通常用于的近似值很重要,如果浮点 0 结果本质上是正数或负数,这很重要。有关详细信息,请参阅https://people.freebsd.org/~das/kahan86branch.pdf

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


推荐阅读