c++ - 与迭代乘法相比,std::pow() 的数值稳定性如何?

标签 c++ floating-point precision floating-accuracy numerical-methods

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

  • 如果已知指数是整数?

  • std::sqrt(x) 如何在稳定性方面与 std::pow(x, k/2) 进行比较>?选择上述方法的首选方法以提高到整数次幂,然后乘以平方根是否有意义,或者我应该假设 std::pow() 对机器来说快速且准确这个精度?如果k = 1,与std::sqrt()有区别吗?

  • std::pow(x, k/2) 或上述方法如何在稳定性方面与 std::sqrt(x )?

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

最佳答案

Will it be more stable (or faster, or at all different) in general to implement a simple function to perform log(n) iterated multiplies if the exponent is known to be an integer?

exponentiation by squaring 的结果整数指数的精度通常不如 pow,但两者在接近输入产生接近结果的意义上都是稳定的。您可以期望通过平方取幂通过乘法引入 0.5 ULP 的相对误差(例如,将 x3 计算为 x * x * x 的 1 ULP 误差)。

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

How does std::sqrt(x) compare, stability-wise, to something of the form std::pow(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。

And as a bonus, what are the speed differences likely to be?

如果您事先知道指数将是一个小整数或 0.5 的倍数,那么您就拥有了 pow 的实现者所没有的信息,因此您可以在确定第二个参数是一个小整数的测试成本最少。此外,质量实现的实现者旨在获得比平方提供的简单求幂更准确的结果。另一方面,pow 的实现者可以使用极其复杂的技术来最小化平均执行时间,尽管准确性更高:例如参见 CRlibm's implementation .在谈论 pow 的最佳实现时,我将上面的动词“保证”放在引号内,因为 pow 是 CRlibm 的 0.5 ULP 精度保证为 only “with astronomical probability” 的一个函数。 .

关于c++ - 与迭代乘法相比,std::pow() 的数值稳定性如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636392/

相关文章:

c - 如何打印 float 的精确值?

mysql - 在Mysql中设置空间精度

c++ - 随机 ascii 字符不断出现在输出中

c++ - 在 mac os x 中制作期间出现错误未知类型名称 'constexpr'

c - 将 char[8] 转换为 double 时出现舍入问题

floating-point - 如何在cygwin中构建软浮点newlib?

java - Java 如何处理多种类型的精度?

Go float64 不适用于经纬度

c++ - 检查容器模板类中的迭代器类型

c++ - C++中双减法的优化