最近,我正在寻找一种更快的替代math exp(x)函数的方法。我找到了非常适合我的东西,通常这种解决方案称为Ankerl算法。参考:
https://github.com/ekmett/approximate/blob/master/cbits/fast.c https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
在C上有典型的Ankerl exp
函数实现
double exp_fast(double a)
{
union { double d; long long x; } u;
u.x = (long long)(6497320848556798LL * a + 0x3fef127e83d16f12LL);
return u.d;
}
int main()
{
for (float x = 0; x < 10; x += 0.01)
std::cout << x << '\t'
<< exp(x) << '\t'
<< exp_fast(x)
<< std::endl;
return 0;
}
很遗憾,我找不到此算法的描述。也许在文学中被称为别的东西。我试图绘制此函数,但感到非常惊讶-这是指数函数的分段线性近似!它在很大的输出值范围内都能完美工作。所有图形都包含大约一千个点(单击以放大)
尽管付出了所有努力,我仍无法确切了解其工作原理。令我惊讶的是,如此简单的代码如何给出如此好的近似值。如果有人可以清楚地说明这是如何工作的,以及从哪些考虑因素中选择了值6497320848556798LL
,0x3fef127e83d16f12LL
,将不胜感激。第二件事-使用这种解决方案是否安全,还是应该避免的肮脏黑客?
答案 0 :(得分:1)
我认为该算法来自Nicol N. Schraudolph发表的论文A Fast, Compact Approximation of the Exponential Function。
本文的“算法”部分说明了其工作原理。并且在那里显示的代码也考虑了机器的耐久性。