Консультация № 179344
29.06.2010, 03:01
0.00 руб.
0 7 1
Здравствуйте,мне нужно реализовать задачу вычисления выражения (a^b)%p для восьмизначных чисел,помогите пожалуйста.

Обсуждение

Неизвестный
29.06.2010, 11:15
общий
это ответ
Здравствуйте, Real27.
Программа. C++. Тестировалась MS VS 2010. Используются специфические для Microsoft типы данных __int32,__int64.

Код:
#include <locale>
#include <iostream>
#include <conio.h>

using namespace std;

typedef unsigned __int32 _uint;
typedef unsigned __int64 _luint;

// Ф-я вычисляющая зачение выражения (a^b)%p
_uint mmod(_uint a,_uint b,_uint p)
{
_luint result=1;
while(b--)
{
result=(result*a)%p;
}
return static_cast<_uint>(result);
}

// 2-я ф-я вычисляющая зачение выражения (a^b)%p
_uint mmod_fast(_uint a,_uint b,_uint p)
{
_luint result=1;
while(b--)
{
if(b&1)
{
a=(static_cast<_luint>(a)*a)%p;
b>>=1;
}
result=(result*a)%p;
}
return static_cast<_uint>(result);
}

int main()
{
locale::global(locale(""));

// Исходные данные
_uint a=55441234,b=76432387,p=12345678;

cout<<'('<<a<<'^'<<b<<")%"<<p<<'='<<mmod(a,b,p)<<endl
<<"2-й вариант:"<<endl
<<'('<<a<<'^'<<b<<")%"<<p<<'='<<mmod_fast(a,b,p)<<endl;

_getch();

return 0;
}


Результат работы
Код:
(55441234^76432387)%12345678=8222230
2-й вариант:
(55441234^76432387)%12345678=8222230
Неизвестный
29.06.2010, 11:30
общий
Огромное спасибо.
Неизвестный
29.06.2010, 14:21
общий
Micren:
Отлично!
Действительно, зачем тащить целую часть от деления? Ее можно отбрасывать на каждой итерации и дальше умножать только остаток.
Неизвестный
29.06.2010, 17:58
общий
amnick:
Цитата: 307758
Отлично!
Ну это уж слишком оптимистичная оценка. Особенно если вспомнить немного математику, а именно an*an=a2n. Что может существенно ускорить вычисление. Только по такой жаре голова пластмассовая работать не хочет.

Немного добавил в ответе.
Неизвестный
29.06.2010, 17:58
общий
Real27:
Посмотрите ответ еще раз. Добавил еще одну функцию.
Неизвестный
29.06.2010, 18:22
общий
Спасибо.
Неизвестный
29.06.2010, 18:39
общий
Micren:
Ну да, стандартный алгоритм быстрого возведения в степень. Я это заметил, но по-моему, здесь не столь существенно (на время выполнения, конечно, влияет заметно при больших степенях). Главное — во избежание переполнения отбрасываем целую часть от деления на каждой итерации.
Форма ответа