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

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

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 is required by the IEEE standard be exact. [sic.]

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

因此,我很想把它重写为1 / std :: sqrt(x),当然是测试.

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

点赞