Ankerl快速指数算法的简单说明

时间:2018-12-21 10:12:18

标签: c++ optimization exp

最近,我正在寻找一种更快的替代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;
}

很遗憾,我找不到此算法的描述。也许在文学中被称为别的东西。我试图绘制此函数,但感到非常惊讶-这是指数函数的分段线性近似!它在很大的输出值范围内都能完美工作。所有图形都包含大约一千个点(单击以放大)

enter image description here enter image description here

尽管付出了所有努力,我仍无法确切了解其工作原理。令我惊讶的是,如此简单的代码如何给出如此好的近似值。如果有人可以清楚地说明这是如何工作的,以及从哪些考虑因素中选择了值6497320848556798LL0x3fef127e83d16f12LL,将不胜感激。第二件事-使用这种解决方案是否安全,还是应该避免的肮脏黑客?

1 个答案:

答案 0 :(得分:1)

我认为该算法来自Nicol N. Schraudolph发表的论文A Fast, Compact Approximation of the Exponential Function

本文的“算法”部分说明了其工作原理。并且在那里显示的代码也考虑了机器的耐久性。