我遇到了一些计算的旧代码
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((的实现中存在错误,这被用作解决方法。
通常,我希望此实现速度较慢且精度较低。