Эффективный способ вычисления p ^ q (экспоненциация), где q - целое число

Что такое эффективный способ вычисления p q где q - целое число?

Ответ 1

Экспоненциация путем возведения в квадрат использует только O (lg q) умножения.

template <typename T>
T expt(T p, unsigned q)
{
    T r(1);

    while (q != 0) {
        if (q % 2 == 1) {    // q is odd
            r *= p;
            q--;
        }
        p *= p;
        q /= 2;
    }

    return r;
}

Это должно работать с любым monoid (T, operator*), где a T, построенный из 1, является элементом идентификации. Это включает все числовые типы.

Расширение этого параметра до signed q легко: просто разделите его на результат выше для абсолютного значения q (но, как обычно, будьте осторожны при вычислении абсолютного значения).

Ответ 2

Предполагая, что ^ означает возведение в степень и что q является переменной времени выполнения, используйте std::pow(double, int).

EDIT: для полноты из-за комментариев по этому вопросу: я задал вопрос Почему std:: pow (double, int) удален из С++ 11? о недостающей функции и фактически pow(double, int) не был удален в С++ 0x, только язык был изменен. Тем не менее, похоже, что библиотеки не могут фактически оптимизировать его из-за проблем с точки зрения точности.

Даже учитывая, что я все равно буду использовать pow, пока измерение не покажет мне, что его нужно оптимизировать.

Ответ 3

Я предполагаю, что вы имеете в виду функцию мощности, а не побитовое xor.

Развитие эффективной силовой функции для любого типа p и любого положительного интеграла q является предметом всего раздела 3.2, в книге Степанова и Макджона Элементы программирования. Язык в книге не С++, но очень легко переведен на С++.

Он охватывает несколько оптимизаций, включая возведение в степень, возведение в квадрат, преобразование в хвостовую рекурсию, затем итерацию и устранение исключений в процессе накопления, а также привязку оптимизаций к понятиям регулярности типа и ассоциативных операций, чтобы доказать, что она работает для всех таких типов.