Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.07.2012, 17:54   #1
Leshii
Форумчанин
 
Регистрация: 26.07.2011
Сообщений: 376
По умолчанию Быстрое возведение в степень.

Доброго времени суток. Требуется помощь с написанием программы. Ниже прилагаю алгоритм решения и свои наработки.

(Условие)Допустим что нам нужно вычислить точное значиние a^n для достаточно большого значение N.

Алгоритм

Если N ( степень ) четное, тогда a^n=(a^n/2)^2. А если N нечетное, то тогда a^n = a*(a^n/2)^2. В любом случае значение показателя степени уменьшено наполовину, а вычисление сведено к, самое большее, двум операциям умножения. Таким образом, для вычисления конечного значения будет достаточно О(lg(n)) операций умножения.

Псевдокод.

Код:
function power ( a, n)
 if ( n = 0 ) return(1)
 x = power(a,n/2)
if  N is even ( четное ) then retrun(x^2)
 else
return(a * x^2);
Проблемы у меня возникли при реализации на паскале, а именно с написанием функции ( настолько привык к ретурнам в С++ что уже подзабыл как в паскале в функции можно обойтись без сего ретурна ).

Код.

Код:
var
 n, pow: longint;
 a: integer;
 s: string//для вывода длинного числа
 
function power( a, n: longint):longint;
var
 x: longint;
begin
if n = 0 then write(1);
x:= power(a,n/2);
if n mod 2 = 0 then power(sqr(x));
else power (a*sqr(x));
power:=x;
end;

begin

read(n);
a:=3;

pow:=power(a,n);
str(pow,s);
writeln(s);

end.
В функции постоянно ругается на типы в месте где выделил красным.
Заранее благодарен за помощь.
Люблю на ты.Я человек простой
Leshii вне форума Ответить с цитированием
Старый 19.07.2012, 19:06   #2
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

n/2 - double
n div 2 - int

если память не изменяет. Кажись еще так можно round(n/2)

Ну а return легко заменить выходом из функции exit;
Result := value; exit;
Kostia вне форума Ответить с цитированием
Старый 19.07.2012, 19:55   #3
Leshii
Форумчанин
 
Регистрация: 26.07.2011
Сообщений: 376
По умолчанию

Благодарю, полезли новые ошибки =) будем разбираться.
Люблю на ты.Я человек простой
Leshii вне форума Ответить с цитированием
Старый 19.07.2012, 21:55   #4
Leshii
Форумчанин
 
Регистрация: 26.07.2011
Сообщений: 376
По умолчанию

Ну собственно вот, что получилось.

Код:
var
 n, pow: longint;
 a: integer;
 s: string//для вывода длинного числа
 
function power( a, n: longint):longint;

begin
if n = 0 then begin
 power:=1;
 exit;
end;

if n mod 2 = 0 then 
power:=sqr(power(a, n div 2));
 else 
power :=a*sqr(power(a, n div 2));

end;

begin

read(n);
a:=3;

pow:=power(a,n);
str(pow,s);
writeln(s);

end.
Люблю на ты.Я человек простой
Leshii вне форума Ответить с цитированием
Старый 19.07.2012, 22:26   #5
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

как-то так:

Код:
function fast_power(a,b: longint): integer;
var
  c: integer;
begin
  if(b = 1) then Result := a
  else
  if(b > 1) then
  begin
    if(b mod 2 = 0) then
      Result := sqr(fast_power(a, b div 2))
    else
      Result := a * sqr(fast_power(a, b div 2));
  end
end;
но от рекурсии я бы избавился.
Kostia вне форума Ответить с цитированием
Старый 19.07.2012, 22:34   #6
spein
Программист
Форумчанин
 
Аватар для spein
 
Регистрация: 27.02.2009
Сообщений: 505
По умолчанию

А не проще ли так?
Код:
{a^(b)}
var:=exp(a*ln(b));
there are no limits when you're software engineer
spein вне форума Ответить с цитированием
Старый 20.07.2012, 02:24   #7
Leshii
Форумчанин
 
Регистрация: 26.07.2011
Сообщений: 376
По умолчанию

насколько помню а^b , а не b^a.( просто потому, что основание то логарифма по формуле а )
Код:
var:=exp(a*ln(b));
Поясню почему не просто

Такого рода задачи, в основном возникают в криптографии при проверке числа на простоту. Проблемы с точностью не позволяют воспользоваться даной форумулой
Код:
exp(b*ln(a))
возведения в степень.

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


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Возведение в степень XYLIGANXYL Общие вопросы по Java, Java SE, Kotlin 7 17.09.2016 15:20
возведение в степень [CODER] Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 6 14.04.2014 10:18
Быстрое возведение в степень.(ошибка) Mahoyn93 Общие вопросы C/C++ 6 15.04.2012 21:58
Возведение в степень. Drakulov Свободное общение 30 01.03.2011 16:35
возведение в степень ILNARM Паскаль, Turbo Pascal, PascalABC.NET 16 16.10.2009 23:04