2
XaositectКажется, приведенный вами алгоритм быстрого возведения в степень (последний) не работает. На самом деле, возводить
в квадрат нужно на
каждой итерации, т.е. примерно так:
Код:
Type PowerBySquaring(Type Base, unsigned long Exponent)
{
type Result=Identity;
while(Exponent)
{
if(Exponent % 2)
{
Result *= Base;
Exponent -= 1;
}
Base *= Base;
Exponent /= 2;
}
}
Используется разложение
где
- цифры двоичного представления числа
. Таким образом для вычисления
необходимо найти последовательность
и бинарное представление показателя степени.
Первая задача решается "в лоб" последовательным возведением в квадрат (
Base *= Base), а вторая переводом числа
в двоичную систему счисления, т.е. последовательным делением на два (
Expoxnent /= 2 или
Exponent >>= 1) с учетом получающихся остатков (наличие единицы в младшем разряде индицируется выполнением условий
Exponent % 2 или
Exponent & 1).
Строка
Exponent -= 1 опциональна и нужна лишь для гарантии правильности округления (до наибольшего целого, меньшего чем частное; aka floor) результата деления на два (для C это гарантируется стандартом).
Этот алгоритм имеет сложность
и работает над
любой (абелевой) полугруппой относительно умножения (моноидом?), что является его главным преимуществом (хоть коров в степень возводи), но умеет возводить числа только в натуральную степень.
Фактическая производительность алгоритма может быть улучшена многочисленными способами (можно разбивать бинарное представление на группы разрядов скользящим окном, разрешить отрицательные биты или использовать addition chain), но на асимптотику это не повлияет (улучшаться будет только константный множитель).
2
Alex696Цитата:
Хотел бы задать вопрос насчет "быстрого" вознесения в степень числа, например
.
Если
или
, то можно заюзать логарифм с экспонентой:
. Это работает достаточно быстро и позволяет возводить числа в произвольные степени, даже в дробные (e.g. при вычислении корней).
Цитата:
Возник вопрос касательно быстрого умножения
Недавно попалась на глаза работка Martin Furer, Faster Integer Multiplication. Довольно интересно.