IEEEfloat64、32和16的754标准使用有符号有效数和有偏指数。作为一名设计硬件架构的学生,对我来说,对有效和指数部分使用二进制补码更有意义。
例如,32位(半精度)浮点数的定义是,第一位代表符号,接下来的8位-指数(偏置127)和最后23位代表尾数。为了实现加法/乘法(负数),我们需要将尾数转换为2的补码并返回。由此产生的硬件相当复杂。
相反,考虑前8位表示指数,后24位表示尾数,两者都是互补的。位移动、加法和乘法相对简单,硬件也不那么复杂。此外,我们有一个唯一的意义零(有符号位表示的两个零)
我花了几个月的时间寻找这些设计决策的原因,发现了这些:
这是真的,我们需要一个加法器(减法器)来比较2的补码。然而,对于流水线架构,如GPU和我自己的基于FPGA的CNN加速器,我们需要避免可变延迟。一点一点迭代地比较一个有符号的表示,使得无法预先确定延迟。在我看来,在这种情况下,减法更好。
也许我们可以为此分配一两个位。并使有意义的23位。
现在这是一个合理的理由。它并不真正适用于我的用例,但我想知道如果他们用一个额外的位来实现它是否会更好。
我的用例
我正在FPGA上构建一个CNN加速器。预定义的乘法和加法延迟以及最小化硬件复杂性对我来说至关重要。我不执行除法,也不用担心inf和NAN。
因此,我决定使用自定义的浮点内部表示,如上所述使用2的补码表示。我应该小心的有什么明显的缺点吗?
这是一个经过充分研究的话题,有些系统使用2的补码浮点表示;通常是IEEE-754之前的那些,尽管最近的化身也是可用的。有关此类系统的属性研究,请参阅本文:https://hal.archives-ouvertes.fr/hal-00157268/document
Kahan本人(IEEE754标准的设计者)确实认为,具有单独的 /-0对于浮点数通常用于的近似值很重要,如果浮点数0的结果本质上是正数或负数,这一点很重要。详见https://people.freebsd.org/~das/kahan86branch.pdf。
所以,是的:完全有可能有2的补码浮点数;但是标准的选择符号大小表示。无论你选择哪一个,有些操作都很容易,有些操作会更难;比较是最明显的。当然,如果你正在设计自己的硬件,没有什么能阻止你选择最适合你需求的表示!特别是,你甚至可以使用所谓的unum's并假设指数和有效部分不是固定大小,而是取决于你在范围内的位置。看这里:https://www.johndcook.com/blog/2018/04/11/anatomy-of-a-posit-number/
2s补码用于整数运算的原因是,它允许相同的硬件和指令用于有符号和无符号运算,在如何检测溢出方面只有微小的差异。使用浮点数,没有人关心“无符号”浮点数,因此如果您在位级别实现它,使用2s补码没有任何好处(节省)。我认为使用2s补码的唯一优势是如果您使用的硬件已经具有某种2s补码ALU。
2s补码在表示上存在较大的不对称问题(可表示值较多