我应该使用 pow 和 sqrt 还是仅使用 pow 来表示半整数?

Con*_*nje 3 c math floating-point gsl

在 C 语言中,我想知道是否有一种“最佳”方法来计算半整数幂。简而言之,问题是计算 x^(n/2) (假设n是奇数且相当小,并且x是一个浮点数)。sqrt(pow(x, n))和之间的性能/准确性是否存在重大差异pow(x, 0.5 * n)?或者甚至反过来:pow(sqrt(x), n)

是否有其他一些实现来处理半整数的这种特定情况?

我的第一个想法是,您只需pow在一次调用中使用和计算整个过程,但我觉得浮点舍入和我失去了问题的一些精度,因为这显然是一半-整数。pow我想如果你使用整数幂并让sqrt处理 (1/2) 部分,也许会有更好的错误性能。

我还注意到 GSL 有计算小整数幂的函数;将这些功能结合起来会sqrt比仅仅使用更好吗pow

我对 C 科学编程还很陌生,所以我不确定我会去哪里寻找类似的实现,而且 Google 还没有真正发现任何东西。

Eri*_*hil 5

在典型的现代处理器中,浮点乘法是一种相当便宜的操作,并且当使用基于二进制的浮点格式时,整数乘以 0.5 不会引入舍入误差。(如果表达式写为n/2,其中n是浮点类型,我希望一个像样的编译器将其实现为乘以 0.5。但是,可以肯定的是,它可以写为n*.5。)

pow是一个复杂的例程,但其执行时间1不太可能受到pow(x, n)pow(sqrt(x), n)或 之间的差异的太大影响pow(x, n*.5)。我们通常可以期望这是计算/2pow(x, n*.5)的好方法。xn

sqrt通常比浮点乘法需要更多的执行时间,并且可能会引入舍入误差。我们可以期望sqrt(pow(x, n))和 中的每一个pow(sqrt(x), n*.5)至少与 一样多的时间pow(x, n*.5),甚至可能更多,但在准确性上没有任何好处。

因此,pow(x, n*.5)是优选的。

我还注意到 GSL 有计算小整数幂的函数;将这些功能结合起来会sqrt比仅仅使用更好吗pow

或许。pow是一个昂贵的例程,因此针对特定功率的定制例程可能会超越它,即使sqrt添加了附加功能。这取决于具体情况,您可能需要进行测量才能知道。

脚注

1执行时间实际上并不是一个单一的东西。执行一个操作不仅会消耗该操作的时间,而且可能会影响现代处理器中并行执行的其他操作,并且可能会影响后续操作的开始时间,并且其自身的开始时间可能会受到其与先前操作的关系的影响。