1

假设我在 x 中有多项式,除以 x 的幂:

p = (a + x(b + x(c + ..)))/(x**n)

抛开效率不谈,这将是更准确的数值计算,上面或使用除法:

p = (((a/x + b)/x + c)/x + ...)

谢谢

4

3 回答 3

5

从理论上讲,应该没有任何区别——如果这些值是以“无限”精度准确计算的。

Kernighan 和 Plauger 在他们古老但出色的著作《编程风格的要素》中指出:

一位聪明的程序员曾经说过,“浮点数就像一堆小沙子,每移动一个,你就会失去一点沙子,得到一点泥土”。

该部门总体上的操作略少,这意味着失去沙子和获得泥土的机会略少。

详细分析可能需要查看系数(a、b、c 等)以及 x 的值——当 x 很大时起作用的方法可能在 x 接近零时不起作用,反之亦然。

于 2009-11-17T03:26:52.953 回答
3

我认为差异很小,除非有可能x**n溢出或下溢,在这种情况下你应该使用第二个表达式。

这两种表达方式在两个地方有所不同:

  1. 第一个表达式的求值顺序相反 (..., c, b, a) 和第二个表达式的 (a, b, c, ...)。哪一个最好取决于系数的值。
  2. 第一个表达式.../x**n的末尾有 。正如 Jonathan 解释的那样,出于这个原因,可以预期第二个表达式更准确,因为它的操作更少。但是,我认为除非上溢或下溢.../x**n,否则只会导致最小的准确性损失(与其他失去准确性的地方相比) 。x**n
于 2009-11-17T11:39:29.953 回答
0

不幸的是,提供的答案是错误的。

第二个方程 p = (((a/x + b)/x + c)/x + ...) 在准确性方面仅差一点点,而在速度方面则差得多。

为什么 ?乘法的相对误差只有一个主要的线性项和一个小的二次项。相比之下,除法引入了更高但非常小的项(三次、四次):

e = 相对误差,假设两项为常数

a*b = a(1+e) b(1+e) = a b (1+2e+e^2) // 乘法

a/b = a(1+e)/b(1+e) = a/b (1+e)(1+e+e^2+e^3+...几何级数) // 除法

所以除法总是比乘法差一点。出于速度考虑:除法总是比乘法慢,正常因子可以在 3x - 10x 之间变化。因此,如果您不是通过 pow() 而是通过嵌套乘法计算最后一个因子 x^n,那么嵌套除法比嵌套乘法慢得多。

x^n 可以很容易地通过循环乘以结果 double power = x; 来计算。对于 (n-1) 次幂 *= x;

如果您使用 pow(),请注意它主要通过指数和对数方便地计算,花费的时间比必要的多得多 (100x)。

您是否知道,虽然双精度结果和精确结果之间的误差仍然很小,但多项式结果对更高 n 的 x 变化非常敏感?!因此,如果您使用更高的 n,请注意您的答案可能完全偏离标准,因为 x 中的小错误会被天文数字放大。

于 2010-01-01T13:05:29.623 回答