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

时间:2019-07-13 06:50:33

标签: floating-point precision

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

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

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

我搜索了几个月,以找出做出这些设计决定的原因,并找到了这些理由:

  1. 2的补码表示法比较起来比较困难。

是的,我们需要一个加法器(减法器)来比较2的补数。但是,对于诸如GPU和我自己的基于FPGA的CNN加速器之类的流水线架构,我们需要避免可变延迟。逐位比较带符号的表示形式使得无法预先确定延迟。我认为,在这种情况下,减法效果更好。

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

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

  1. +0和-0零,因此1 / + 0 = + inf和1 / -0 = -inf

现在,这是一个正当理由。它不是真的适用于我的用例,但是我想知道如果他们再增加一点实现会更好。

我的用例

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

因此,我决定如上所述使用二进制补码表示法来使用浮点的自定义内部表示法。我应该注意哪些明显的不利之处?

2 个答案:

答案 0 :(得分:4)

这是一个经过充分研究的主题,并且有 个系统使用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/

答案 1 :(得分:1)

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

2s补码的表示形式存在较大的不对称性问题(<0比> 0更具可表示性),如果您尝试在需要舍入或精度可能降低的任何情况下使用它,都会引起各种数学稳定性问题,例如浮点数通常用于。