浮点乘法与多次加法的比较

Floating point multiplication compared to multiple additions

好吧,我们假设 a 是基数 2(二进制系统)中的归一化浮点数。以下等式是否正确?

fl(a+a+a)=fl(3*a)

符号和先决条件

a表示一个数学数字。 a 表示一个浮点值。 3a表示一个数学表达式(使用实数运算)。 a+a+a3*a 表示使用浮点运算的表达式。

典型浮点系统中算术的一个基本特征是,浮点运算的结果被定义为在某个方向(通常是在最近的可表示值与偶数低位的可表示值相关联,但可以选择其他方向)。1

有限的正常值

在二进制浮点数中,如果a是可表示的且2a在有限范围内,则2a 是可表示的,因为它们表示的唯一区别在于指数。因此,给定一个浮点数a表示数aa+a的结果正好是2a .那么a+a+a(也就是(a+a)+a)的浮点数结果就是数学结果3a(因为数学结果是2a +a) 四舍五入到最接近的可表示值。 3*a 的浮点结果也是数学结果 3a 四舍五入到最接近的可表示值。因此a+a+a3*a有相同的浮点数结果,等式成立。

特例

还有待考虑特殊情况

如果a表示a是有限的,但是2a超出了浮点数的范围结果是有限的,那么a+a产生无穷大,a+a+a产生同样的无穷大,3*a也是如此,所以等式成立。

如果a是无穷大,则a+aa+a+a3*a产生相同的无穷大,等式成立。

如果 a 是一个 NaN,那么 a+a+a3*a 都是 NaN,并且它们不会比较相等,因为两个 NaN 永远不是具有相等值的数字。

脚注

1 题中没有说明使用的浮点数系统。当然可以定义一个浮点系统,其中 1+1 产生 00+1 产生 0,而 3*1 产生 5。但是,为了这个答案的目的,我们假设一个典型的浮点系统。

您没有指定格式,IEEE 754 很流行,但不是唯一的标准。

作为一般规则,不要对浮点使用相等,因为浮点二进制格式与无限精确的数字不同。假设在一侧有两个操作而另一侧有一个操作的情况下,每个操作都可以裁剪,因此每个操作的精度损失应该是预期的,两个操作可能 lose/change 多于一个操作。如果格式和实现的一部分在特定情况下可以帮助消除部分损失,则四舍五入,但这不是一个完整的修复,有时会造成伤害。

所以通常不要假设这会起作用,但在这种特定情况下,让我们从 IEEE 样式格式开始 1.fraction,我们不需要很多尾数来了解它如何有效。

1.abc(a,b,c 为单个位)

正如 Eric 指出的那样,从 2*a 开始

  1abc
+ 1abc
========
 1xxx0

无论c是1还是0,lsbit都是0。定点1abc+1abc = 2*1abc只要不溢出指数即可:

  1abc
+ 1abc
========
 1abc0

如果愿意,您可以了解尾数位的组合和数量。

加a+a+a到此为止

 1abc0
+ 1abc
=======

对于乘法的情况

    1abc
    1100
  ====== 
    0000
   0000
  1abc
+1abc
===========

走到这一步

   1abc
+ 1abc0
========

所以他们在同一个地方结束,他们是平等的,是吗?

此处舍入不是一个因素,因为较低的位通过任一路径产生相同的值...是吗?

例如 IEEE 中的负数也使用正数 1.f 格式并且符号单独处理。在这种情况下,乘法路径 p * p 为正 p * n 为负,因此两条路径都有效,您保留符号(此处 3 始终为正)。对于加法路径,结果要么变得更负,要么更正,它们保留其符号。

第一次加法会导致指数溢出,例如在 IEEE 中会导致 NAN。第二个添加,同样的故事。乘法也可能导致 NAN,并且最好假设通过两条路径,两个 NAN 结果不是二进制相等的,因此比较将不起作用。如果我没记错的话,一个会发信号,另一个会安静是吗?

其他格式。仍在努力应该像 1.f 类型格式一样容易演示。例如正数 01.fraction,负数 10.fraction。

这里的关键是乘法的实现应该支持 2n 所需的位数(对于定点 n 位 * n 位 = 2n 位将涵盖所有情况 32 位数字乘以 32 位数字需要 64 位来存储它。)格式倾向于在值的顶部强制一个 1 意味着你乘以 1xxxxx... * 1xxxxx.... 来自小学

a.bcd
e.fgh
======

我们会以定点 abcd * efgh 的形式进行数学计算,然后自动将结果中的小数点移动 6。然后二进制浮点数将需要归一化并根据格式将最高有效的 1 或 0 移动到二进制小数点的左侧,调整指数,类似于我们在科学记数法中使用 10 的幂来进一步调整结果.理想情况下,逻辑将使用足够的位来使定点数学运算正确,然后对其进行归一化,然后裁剪并可能舍入。

所以在一天结束的时候你会看到类似

的东西
     abcd
    abcd
   abcd
  abcd
+ ...

对于 3*a 与 a+a+a 的情况

最好将 c 保留为粘性位

 1abc0
+ 1abc
=======
 xxxxx

最坏的情况剪辑它

 1abc0
+ 1abc
=======
 xxxx  

乘法

最佳情况

    0000
   0000
  1abc
+1abc
===========
 xxxxxxx`

最坏情况裁剪

    0 
   00 
  1ab 
+1abc
===========
 xxxx`

在这两种情况下,我们 keep/lose 如果加法和乘法都进行相同的优化,则沿着两条路径的单个位会产生相同的结果。这只是 3*a vs a+a+a 的情况,必须遍历任何其他方程式的可能性。

底线:假设使用无限精度数学计算完全相等的方程式使用二进制浮点数学计算不相等。但是有些情况可以证明是相等的(取决于实现),我认为这些例外不是规则。

假设一种方法,如果它不是,那就高兴,如果你能证明它不是(对于你的特定目标硬件或一般格式),那么更好,然后记住并记录该证明的局限性。如果您忘记了证明或没有记录规则,那么稍后会有人出现并搞砸并且数学 can/will 是错误的并且软件将无法运行。因此,在进行数学优化时要非常非常小心,不要仔细考虑它们。特别是如果您希望进行相等比较。

我在控制系统上工作,我们必须修改尾数的 lsbit 才能使数学工作,计算常量前门没有产生正确的值集。对该控制系统参数的任何进一步调整都需要检查这些值,并可能调整其中一个或多个值以使数学计算起作用。