与迭代乘法相比,std::p ow() 的数值稳定性是多少?

What is the numerical stability of std::pow() compared to iterated multiplication?

本文关键字:稳定性 多少 迭代 std ow      更新时间:2023-10-16

使用std::pow()会出现或解决什么样的稳定性问题?

  • 如果已知指数是整数,实现一个简单的函数来执行迭代乘法log(n)通常会更稳定(或更快,或完全不同)吗?

  • 稳定性方面,std::sqrt(x)std::pow(x, k/2)形式相比如何?选择上述方法提高到整数幂,然后乘以平方根是否有意义,或者我应该假设std::pow()快速且精确到机器精度?如果k = 1,与std::sqrt()有区别吗?

  • std::pow(x, k/2)或上述方法在稳定性方面如何与std::sqrt(x)的整数幂进行比较?

作为奖励,速度差异可能是多少?

如果指数已知为整数,则实现一个简单的函数来执行log(n)迭代乘法,通常会更稳定(或更快,或完全不同)吗?

整数指数平方的求幂结果通常不如pow精确,但两者都是稳定的,因为接近输入产生接近的结果。您可以期望通过平方的幂通过乘法引入 0.5 ULP 的相对误差(例如,计算 1 ULP 的误差 x3 作为x * x * x)。

当第二个参数 n 静态已知为 2 时,则一定要实现 xn 作为 x * x 。在这种情况下,它比任何可能的替代方案都更快、更准确。

std::sqrt(x) 在稳定性方面与 std::p ow(x, k/2) 的形式相比如何

首先,对于IEEE 754实施来说,sqrt的准确性是无与伦比的,因为sqrt是该标准要求尽可能准确的基本操作之一。

但是你不是在问sqrt,而是在问(我认为)关于n> * sqrt(x)的计算,而不是pow(x, n + 0.5)。同样,一般来说,对于 pow 的质量实现,您可以期望pow(x, n + 0.5)比替代方案更准确。尽管sqrt(x)将计算为 0.5 ULP,但乘法引入了其自身高达 0.5 ULP 的近似值,总而言之,最好在对实现良好的函数的单次调用中获得您感兴趣的结果。pow 的质量实现将为您提供 1 ULP 的准确度,而最好的实现将"保证"0.5 ULP。

作为奖励,速度差异可能是多少?

如果您事先知道指数将是小整数或 0.5 的倍数,那么您拥有pow的实现者没有的信息,因此您至少可以击败它们测试的成本来确定第二个参数是小整数。此外,质量实现的实现者的目标是获得比平方提供的简单幂更准确的结果。另一方面,pow的实现者可以使用极其复杂的技术来最小化平均执行时间,尽管准确性更高:例如参见CRlibm的实现。在谈论pow的最佳实现时,我将动词"保证"放在引号内,因为pow是CRlibm的0.5 ULP精度保证仅"具有天文概率"的一个函数。