1/sqrt(x) 和 std::exp(-0.5 * std::log(x)) 之间的数值权衡

Numerical trade offs between 1/sqrt(x) and std::exp(-0.5 * std::log(x))

本文关键字:std 之间 log 权衡 exp sqrt      更新时间:2023-10-16

我遇到了一些计算的旧代码

double y = 1 / std::sqrt(x);

用:

constexpr double base16 = 16.0;
double log_base16 = std::log(base16);
double y = std::pow(base16, -0.5 * std::log(x) / log_base16);

这本质上是:

double y = std::exp(-0.5 * std::log(x));

方法之间的数值优势(例如准确性或更有可能避免下溢/溢出(方面是否有任何理由?原作者可能也是这么认为的。

原始代码确实被认为非常顽皮,特别是在现代C++标准和浮点IEEE754:

std::sqrt 是 IEEE 标准所要求的精确。[原文如此]

此外,std::pow没有这样的要求。

因此,我很想将其重写为1 / std::sqrt(x),当然是测试。

参考: http://en.cppreference.com/w/cpp/numeric/math/sqrt

我看不出有任何特别好的理由在pow((和log((方面实现sqrt((。可能是sqrt((的实现中存在错误,这被用作解决方法。

通常,我希望此实现速度较慢且精度较低。