Простое объяснение алгоритма быстрого показателя Анкерля - PullRequest
0 голосов
/ 21 декабря 2018

Недавно я искал более быструю альтернативу математической функции exp (x).Я нашел что-то, что мне очень понравилось, чаще всего это решение называется алгоритмом Анкерля.Ссылка:

https://github.com/ekmett/approximate/blob/master/cbits/fast.c https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/

Существует типичная реализация функции Ankerl exp на C

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

Я не мог понять, как именно это работаетнесмотря на все усилия.Меня удивляет, как такой простой код может дать такое хорошее приближение.Буду очень признателен, если кто-то сможет четко объяснить, как это работает и из каких соображений выбраны значения 6497320848556798LL, 0x3fef127e83d16f12LL.И второе - безопасно ли использовать такое решение или это своего рода грязный взлом, которого следует избегать?

1 Ответ

0 голосов
/ 21 декабря 2018

Я думаю, что этот алгоритм взят из статьи Быстрое, компактное приближение экспоненциальной функции , представленной Николом Н. Шраудольфом.

В разделе «Алгоритм» статьи объясняется, как он работает.И код, представленный там, также учитывает порядок машин.

...