Что такое эффективный способ вычисления 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, в книге Степанова и Макджона Элементы программирования. Язык в книге не С++, но очень легко переведен на С++.
Он охватывает несколько оптимизаций, включая возведение в степень, возведение в квадрат, преобразование в хвостовую рекурсию, затем итерацию и устранение исключений в процессе накопления, а также привязку оптимизаций к понятиям регулярности типа и ассоциативных операций, чтобы доказать, что она работает для всех таких типов.