Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Pascal] Вычислить значение функций


Автор: Koschei 12.10.2006, 16:12
Вычислить значение функций "на рисунке" с точностью E=10^-4,где x изменяется от 0,2 до 2 с шагом 0.1.
вычисление y оформить в функцию,результаты вывести в виде таблицы.


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

Автор: Snowy 12.10.2006, 16:19
Перенесено из Паскаля

Автор: Alexeis 12.10.2006, 16:23
Модератор: название скорректировано в соответствии с правилами раздела

Добавлено @ 16:33 
Koschei, неразборчиво формула написана.

Автор: Alexeis 12.10.2006, 17:19
Если я правильно разобрал что там написано, то так.
Код

program Project2;
const
  err = 1e-4;

function f(x : double) : double;
var
  n    : integer;
  s, c : double;
  sign : integer;
  fact : double;

Begin
  sign := 1;
  fact := 3 * 2;
  s := 0;
  n := 1;
  repeat
    c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
    s := s + c;
    sign := -sign;
    inc(n);
    fact := fact * (2 * n) * (2 * n + 1);
  until abs(c) < err;
  f := s;
end;

var
  x : double;
begin
  x := 0.2;
  Repeat
    Writeln('x= ', x : 1 : 1, '  f= ', f(x) : 2 : 4);
    x := x + 0.1
  until x >= 2.001;
  readln;
end.

Автор: Koschei 13.10.2006, 12:23
Рисунок поменял.
А текстовый алгоритм никто не поможет написать?хотя бы коротенький из нескольких строк...
alexeis1
чего то задача не работаетsmile,переписал вроде правильно.У тебя она работала?

Автор: Alexeis 13.10.2006, 13:03
Цитата(Koschei @  13.10.2006,  12:23 Найти цитируемый пост)
У тебя она работала?

Да но в консоли в делфи, в сам паскаль я не лез.

Добавлено @ 13:13 
Цитата(Koschei @  12.10.2006,  16:12 Найти цитируемый пост)
написать текстовый алгоритм

это слишком абстрактная задача...

Автор: Koschei 13.10.2006, 13:21
текстовый алгоритм типа что то этого:
1. Запрашиваем n (до какой степени решать), x(значение угла) числа.
2. Считываем и заносим в переменные n и x соответственно.
3. С помощью цикла высчитываем все значения заданной функции.
4. Во время выполнения цикла суммируем значения функции в нейтральную переменную.
5. Выводим результат на экран
вот текстовый алгоритм для другой задачи.
alexeis1 А команды дельфи отличаются от паскаля?видно то будет что сделано в дельфи,а не на паскале?(может звучит глупо конечно,но хотелось бы уточнить)
ошибку выдает вот эта команда:fact := 3 * 2; пишет что:error 116:must be in 8087 mode to compile this.
Не обьясниш что за ошибка?
Все прога работает!урааа!спасибо вам!

Автор: Kuvaldis 13.10.2006, 13:56
Koschei, 
После консультаций с Alexseis1 пришли к выводу, что программа правильная, но..
для Паскаля в начале программы нужно включить директиву компилятора о разрешении работы сопроцессора (первой срокой)
Код

{$N+}


Текстовый алгоритм:
Функция f:

1. Инициализируем локальные переменные
2. Вычисляем текущий член суммы
3. Добавляем его к суммы
4. Если текущий член суммы больше заданной точности, то переход на шаг 2.
5. Возвращаем в вызывающую функцию полученную сумму.

Главная функция

1. Инициализируем переменные
2. Во время выполнения цикла выводим аргумент и значение функции на экран для заданного интервала

Автор: Koschei 13.10.2006, 14:29
Может это покажется вверх наглости,но не могли бы вы уважаемые написать что каждый шаг делает?
Например:
var
  n    : integer;
  s, c : double;         = здесь идет перечисление "переменных"
  sign : integer;
  fact : double;   
А то как мне обьснить преподу что и как у меня получилось?

Автор: Alexeis 13.10.2006, 14:46
присвоение начальных значений sign - знак +-, fact - вычисление факториала s - накапливет сумму (все члены) n - номер члена 
Код

 sign := 1;
  fact := 3 * 2;
  s := 0;
  n := 1;


c - расчет текущено члена s - добавление значения очередного члена к общей смме
Код

    c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
    s := s + c;
    sign := -sign; // чередуем знак
    inc(n);            // увеличиваем счесчик n на единицу
    fact := fact * (2 * n) * (2 * n + 1); // вычисляем факториал для следующего шага


Код

....
 until abs(c) < err; // выполняем пока очередной член не станет меньше заданной погрешности
  f := s; // возвращаем результат функции.



Ну а вывод на экран надеюсь ясен? просто в цикле распечатка значений функции, правда счетчик уже с плавающей запятой.

Автор: Koschei 13.10.2006, 15:23
Вот это вы молодцы!Спасибо еще раз!Выташили меня,из омута долгов!

Автор: Alexeis 13.10.2006, 18:07
Цитата(Koschei @  13.10.2006,  15:23 Найти цитируемый пост)
Выташили меня,из омута долгов! 

Только вот надо галочку ставить что вопрос решен. (Ладно уж поставлю сам smile )

Автор: Koschei 14.10.2006, 11:03
оказывается нужно коффициэнт в рекурентном соотношении найти сначала!помогите доделать.пожалуйста,а то преподователь так не принимает smile 

Автор: Alexeis 14.10.2006, 11:53
Цитата(Koschei @  14.10.2006,  11:03 Найти цитируемый пост)
оказывается нужно коффициэнт в рекурентном соотношении найти сначала!

Чтоб упростить задачу и сделать ее более прозачной я вообще отказался от рекурсии. Ее просто НЕТ smile 
Рекурентное вычисление факториала заменено, на пошаговое, что намного эффективней. Посдите сами при рекурсии надо каждый раз вычислять
1*2*3
1*2*3*4*5
1*2*3*4*5*6*7

А я сделал проще
fact := 1*2*3
fact := fact    *4*5 
fact := fact            *6*7

ИМХО тут рекурсия нужна как телеге 5-е колесо. 

Автор: Koschei 14.10.2006, 12:01
alexeis1, 
так препод требует именно в коофицент в рекуретном найти!другие способы ему не нужны!пожалуйста напишите именно в рекуретном!
и можно написать весь текст программы сразу с рекуретном методом?

Автор: Kuvaldis 14.10.2006, 12:26
Koschei, 

alexeis1 прав, даже не обязательно вычислять каждый раз x^n = exp(ln(x)) . Можно (и нужно) заметить, что x^n = x * x^(n-1)
Но если тебе уж очень приспичило, то вот вариант с "полноценным" вычислением факториала
Код

{$N+}

const
  err = 1e-4;
//******************************************************************************
function factorial(n : integer) : integer;
var
   f, i : integer;
begin
   f := 1;
   for i := 2 to n do
       f := f * i;
   factorial := f;    
end;
//******************************************************************************
function f(x : double) : double;
var
  n    : integer;
  s, c : double;
  sign : integer;
  fact : double;
Begin
  sign := 1;
  s := 0;
  n := 1;

  repeat
      fact := factorial(2 * n - 1);
      c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
      s := s + c;
      sign := -sign;
      inc(n);
  until abs(c) < err;

  f := s;
end;
//******************************************************************************
var
  x : double;
begin
  x := 0.2;
  Repeat
    Writeln('x= ', x : 1 : 1, '  f= ', f(x) : 2 : 4);
    x := x + 0.1    
  until x >= 2.001;    
  readln;
end.
//******************************************************************************


Автор: Alexeis 14.10.2006, 13:40
Да это сложнее и рекурсивный алгоритм как вегда, для тех кто не боится мозг свернуть.
Код

program Project2;

{$N+}

const
  err = 1e-4;

var
  sign : integer;
  fact : double;
  level: Integer;

function Recur(x : Double; n : integer) : Double;
var
  c : double;

begin
  if n = 1
  then
    begin
      sign := 1;
      fact := 3 * 2;
      n := 1;
      c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c;
          level := 1;
        end;
    end
  else
    begin
      c    := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
      sign := -sign;
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1);

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c;
          level := n;
        end;
    end;
end;

var
  x : double;
begin
  x := 0.2;
  Repeat
    Writeln('x= ', x : 1 : 1, '  f= ', Recur(x, 1) : 2 : 4, ' n=', level);
    x := x + 0.1
  until x >= 2.001;
  readln;
end.


Модератор: На будщее читайте правила.

Правила (пункт 10): Если вы хотите, чтобы вашу проблему решили при помощи определенного 

алгоритма, то не забудьте описать его! 

Автор: Koschei 15.10.2006, 06:27
Спасибо,теперь надеюсь препода это устроит.А то виделите подрозумевалось таким образом решать именно...

Автор: Koschei 19.10.2006, 10:42
блин мне не рекурсия нужна,а рекуретный коофициент вычислить!вообшем вычислить значение функций с помошью рекуретного алгоритма!помогите,а?

Автор: Alexeis 19.10.2006, 13:34
Вы противоречите сами себе 
Цитата(Koschei @  19.10.2006,  10:42 Найти цитируемый пост)
блин мне не рекурсия нужна


Цитата(Koschei @  19.10.2006,  10:42 Найти цитируемый пост)
вообшем вычислить значение функций с помошью рекуретного алгоритма!помогите


Это одно и тоже. Раберитесь наконец с формулировкой задачи, потому как узнать о чем думает ваш преподаватель я точно не в силах. smile 

Автор: Koschei 19.10.2006, 18:47
задача ток решена неправильноsmile этим рекуретным алгоритмом.С ответом прошлого решения не сходится.а там ответ правильный ибо преподаватель ответ проверял..

Автор: Alexeis 19.10.2006, 20:01
Код

program Project1;

{$N+}

const
  err = 1e-4;

var
  sign : integer;
  fact : double;
  level: Integer;

function Recur(x : Double; n : integer) : Double;
var
  c : double;

begin
  if n = 1
  then
    begin
      sign := 1;
      fact := 3 * 2;
      n := 1;
      c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
      sign := -sign;
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1);

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c;
          level := 1;
        end;
    end
  else
    begin
      c    := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
      sign := -sign;
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1);

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c;
          level := n;
        end;
    end;
end;

var
  x : double;
begin
  x := 0.2;
  Repeat
    Writeln('x= ', x : 1 : 1, '  f= ', Recur(x, 1) : 2 : 4, ' n=', level);
    x := x + 0.1
  until x >= 2.001;
  readln;
end.


Автор: Koschei 27.10.2006, 12:39
А не могли бы вы написать текстовый алгоритм?как на той страницеsmileбуду очень признателен!

Автор: Alexeis 27.10.2006, 14:02
Koschei, так ты бы сказал, что конкретно надо! Выводится и так все в текстовом виде. Побольше конкретики. Откуда же мне знать, в каком виде у вас там принято оформлять. 

Автор: Koschei 27.10.2006, 14:42
Не вы не поняли уважаемые,под текстовым алгоритмом я имел ввиду это:
Текстовый алгоритм:
Функция f:

1. Инициализируем локальные переменные
2. Вычисляем текущий член суммы
3. Добавляем его к суммы
4. Если текущий член суммы больше заданной точности, то переход на шаг 2.
5. Возвращаем в вызывающую функцию полученную сумму.

Главная функция

1. Инициализируем переменные
2. Во время выполнения цикла выводим аргумент и значение функции на экран для заданного интервала

и для полного счастья:
Не могли бы вы уважаемые написать что каждый шаг делает?
Например:
var
  n    : integer;
  s, c : double;         = здесь идет перечисление "переменных"
  sign : integer;
  fact : double;   
А то как мне обьснить преподу что и как у меня получилось?
p.s.а точно прокатит рекурсия?"если препод точно имел ввиду рекуретность?" 
А не могли бы вы как-нибудь по простому сделать.чтоб было видно что первокурсник сделал,а то как вы сделали у нас на курсе таких команд не знают дажеsmile

Автор: Alexeis 27.10.2006, 15:02
Цитата(Koschei @  27.10.2006,  14:42 Найти цитируемый пост)
А не могли бы вы как-нибудь по простому сделать.чтоб было видно что первокурсник сделал,а то как вы сделали у нас на курсе таких команд не знают даже


Каких команд не знают?

Вообще-то рекурсия вещь непростая сама по себе, и алгоритмы получаются хочешь не хочешь, закрученными. Я сам мозг чуть не свернул smile. 

Давайте вначале с командами разберемся.

Автор: Koschei 27.10.2006, 15:07
Цитата

Каких команд не знают?

ну например эти
recur
sign

Автор: Alexeis 27.10.2006, 15:26
recur - это не команда, а просто имя функции которая вызывает сама себя т.е. рекурсивной. Его можно заменить хоть на Vasea_Pupkin smile 

sign = это имя переменной, которая хранит значения знака члена ряда. (он же чередуется плюс / минус), вот она и меняет значение -1 +1.

Какие еще названия не ясны?

Автор: Koschei 27.10.2006, 18:51
Цитата

Какие еще названия не ясны? 

ну с остальными ясно.
Мне бы текстовой алгоритмик и что действия обозначают;)А то без этого мне серавно не сдать лабу...
p.s.задача не решена правильно ибо опять ответ с первым решением(тот который не рекуретным сделан) не сходится smile (а там решено правильно),да еще какая то n появилось в ответе.это вообше чего такое?

Автор: Koschei 28.10.2006, 10:42
Товариши не бросайте меня на пол пути.помогите сделать все правильно! smile 

Автор: Alexeis 28.10.2006, 19:00
Я не бросаю, просто у меня проблемы с конектом.
Код

function Recur(x : Double; n : integer) : Double;
var
  c : double;

begin

Эта функция за один вызов считает один член.
Все члены вычисляются последовательно от первого до последнего, потому вызов производится так
Recur(x, 1) 
Код

var
  x : double;
begin
  x := 0.2;
  Repeat
    Writeln('x= ', x : 1 : 1, '  f= ', Recur(x, 1) : 2 : 4, ' n=', level);
    x := x + 0.1
  until x >= 2.001;
  readln;
end.


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

if n = 1 //если первый член
  then
    begin
      sign := 1; //у первого члена знак +1
      fact := 3 * 2; // (2*(1)+1) = 3 - т.е считаем факториал 3-х
      n := 1;                  // гы. это осталось от прошлого решения оно нифига не делает его нужно удалить
      c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact); //вычисляем очереднойчлен т.е. в данном случае первый
      sign := -sign;        //меняем знак (для вычисления следующего члена)
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1); //вычисляем факториал для следующего члена (5!)

      if Abs(c) > Err (если значене члена по мдулю болше погрешности то вычисляем рекурсивно второй член (а в нем может быть третий, четверый и т.д.))
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c; //иначе говорим что все нашли с задой точностью и возвращаем значение
          level := 1; //и глубину
        end;
    end


exp(n * ln(x)) - так вычисляется значение x^n.

Код

else //это код вычисления членов 2 и выше
    begin
      c    := sign * exp(n * ln(x)) / ((2 * n - 1) * fact); //все переменные вычислены на предыдущем шаге, потому сразу вычисляем очередной член (формула та же что и для первого)
      sign := -sign; //чередум знак 
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1); //вычисляем факториал следующего нечетного числа

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1) //аналогично, если член больше погрешности, что считаем следующий и сумируем его с текущим.
      else
        begin
          Recur := c; //или просто возвращаем значение, если он меньше.
          level := n; //и глубину 
        end;
    end;
end;


если посмотреть, то в рекурсивную функцию каждый раз передается номер больший на 1 
Recur := c + Recur(x, n + 1) - так и осущиствляется инкримет членов.

Автор: Koschei 28.10.2006, 19:58
Да но товариш родной,задача с первым решением не сходитсяsmile,а там как я уже говорил ответ правильный!отсюда вывод что задача рекурсией неправильна!помогите переделать  люди,а то я скоро буду в армииsmile..

Автор: Alexeis 28.10.2006, 20:25
Как не сходится. Тот самый последний вариант сходится. Я специально проверял после исправления! Запускал оба варианта и смотрел по содержимому окон. Наверное проверялся не самый последний вариант.

Добавлено @ 20:27 
Вот ссылка на уже верный вариант http://forum.vingrad.ru/index.php?showtopic=116158&unread=1&st=30&#

Автор: Koschei 29.10.2006, 08:38
Цитата

http://forum.vingrad.ru/topic-116158/unread-1/30.html

Вроде код не по порядку написан,может быть сразу напишеш готовый текст программы?

Автор: Alexeis 29.10.2006, 13:54
Цитата(Koschei @  29.10.2006,  08:38 Найти цитируемый пост)
может быть сразу напишеш готовый текст программы? 

Так я же дал ссылку на готовый код. Коментарии писал для того чтобы было понятно как работет. Что неужели так сложно из этого скомопновать то что нужно?

Автор: Koschei 29.10.2006, 17:25
Цитата


Так я же дал ссылку на готовый код. Коментарии писал для того чтобы было понятно как работет. Что неужели так сложно из этого скомопновать то что нужно?



Меня ссылка опять на эту страницу выкидываетsmile.Пожалуйста напиши его сюда!
Или ты имел ввиду этот верхний(всмысле вверху страницы) строчки кода?так я непонял чего  и куда писатьsmile.Можеш тогда сразу нормально написать?а то блин не выхордит у меня smile 

Автор: Alexeis 29.10.2006, 18:26
Цитата(Koschei @  29.10.2006,  17:25 Найти цитируемый пост)
Меня ссылка опять на эту страницу выкидывает

правильно это же ссылка на пост который работает уже так как надо. Пока страница грузится нужно подождать. В конце загрузки будет виден нужный пост.

Автор: Koschei 29.10.2006, 20:12
Цитата

правильно это же ссылка на пост который работает уже так как надо. Пока страница грузится нужно подождать. В конце загрузки будет виден нужный пост.

не вижу хоть убей.может куда-нибудь перезальеш?или в личку кинеш?

Автор: Alexeis 29.10.2006, 20:28
Код


program Project1;

{$N+}

const
  err = 1e-4;

var
  sign : integer;
  fact : double;
  level: Integer;

function Recur(x : Double; n : integer) : Double;
var
  c : double;

begin
  if n = 1
  then
    begin
      sign := 1;
      fact := 3 * 2;
      n := 1;
      c := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
      sign := -sign;
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1);

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c;
          level := 1;
        end;
    end
  else
    begin
      c    := sign * exp(n * ln(x)) / ((2 * n - 1) * fact);
      sign := -sign;
      fact := fact * (2 * (n + 1)) * (2 * (n + 1) + 1);

      if Abs(c) > Err
      then
        Recur := c + Recur(x, n + 1)
      else
        begin
          Recur := c;
          level := n;
        end;
    end;
end;

var
  x : double;
begin
  x := 0.2;
  Repeat
    Writeln('x= ', x : 1 : 1, '  f= ', Recur(x, 1) : 2 : 4, ' n=', level);
    x := x + 0.1
  until x >= 2.001;
  readln;
end.


Автор: Koschei 29.10.2006, 21:12
Все спасибо огромное программа отлично работает!
p.s.Ток один вопрос зачем в ответе n выводится?

Автор: Alexeis 29.10.2006, 21:44
Цитата(Koschei @  29.10.2006,  21:12 Найти цитируемый пост)
p.s.Ток один вопрос зачем в ответе n выводится? 

Так это и есть уровень рекурсии (или ее глубина)  который требовался по условию. Он же и является числом членов вычисленных в сумме.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)