Pascal. Вычислить функцию. Проблема с типами.

Ответить
baranker
Сообщения: 13
Зарегистрирован: 14 дек 2008, 22:54

народ у меня задача я вроде все написал да мои алгоритмы не подходят слишком большие числа в этой задаче прошу вас о помощи может вы можете мне чем-нибудь помочь?задача turbo pascal
дано X
определить

y=значек суммы (n=2 до 14) x^(2n-2)/(2n+1)!

думаю все надо делать через функцию по крайней мере я так делал но все неудачно!
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Перенес в отдельную тему.

Может у Вас дело не в алгоритме, а просто в типах? Может вместо real можно поставить double?

А еще может быть у вас просто где-то зацикливание происходит и поэтому переполнение?

В любом случае покажите свой вариант.
baranker
Сообщения: 13
Зарегистрирован: 14 дек 2008, 22:54

так я не очень разобрался в этих функциях!если че не то громко не смеяться

Код: Выделить всё

program g1_94_5;
{дано x;
определить  Y=14сумма n=2  x^(2n-2)/(2n-1)!}
var
x:real;
k,j,n,i,znam,p:integer;
   y,chisl:real;
 begin
 writeln('BBEdi x  ');
 read(x);
 chisl:=sqr(1/x);
    y:=0; p:=2;i:=4;
    k:=6;
    for n:=2 to 14 do
       begin
        chisl:=sqr(sqr(x))*chisl;
           k:=(2*n+1)*k*2*n;
           znam:=k;
           writeln;
           writeln('chisl= ' ,chisl:8:2);
           writeln('znam= ',znam);
           end;
           y:=y+chisl/znam;
            writeln;
      writeln('y=',y );
      readln;
 end.
вот  тут ошибочен числитель не так считает со знаменателем(т.е.) факториалом он останавливается на каком то шаге вроде как из-за большого слишком числа!
function power (const x:real;const n:byte):real;
 var
    i,znam,p:integer;
  res,chisl:real;
 begin
    result:=0; chisl:=1; znam:=1; p:=2;
     res:=1;
     for n=2 to 14 do
    for i:=1 to 2*n-2 do res:=res*x;
    power:=res;
вот я функцию составил по возведению в степень проверьте пожалуйста!

Esgal
Сообщения: 78
Зарегистрирован: 04 ноя 2008, 01:15

[syntax='Delphi']

program SumSP;
uses crt;
var x:real;
y:real;
i:byte;

function fact(n:integer):longint;
begin
if n=1 then
begin
fact:=1;
exit;
end;
fact:=fact(n-1)*n;
end;

function degree(bas:real;deg:byte):real;
begin
degree:=exp(deg*ln(bas));
end;

{y=значек суммы (n=2 до 14) x^(2n-2)/(2n+1)!}
function fx(z:real;m:byte):real;
begin
fx:=degree(z,2*m-2)/fact(2*m+1)
end;

begin
clrscr;
write('');
readln(x);
y:=0;
for i:=2 to 14 do y:=y+fx(x,i);
writeln('',y:3:5);
readln;
end.

[/syntax]
Не тестил, прямо сюда написал... советую потестить и посмотреть подходят ли типы... возможно придётся использовать дабл или экстендет
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Переобъявил переменные так:

x,k:extended;
n:longint;
j,i,p:integer;
y,chisl:extended;

Так как 29! не поместится ни Integer, ни в Longint.
Остается только сопроцессорный тип extendeded, и приближённые вычисления.
В типе extended 29!=8,8417619937397E+30
baranker
Сообщения: 13
Зарегистрирован: 14 дек 2008, 22:54

господа а можно чтобы в степень не через exp возводить в этой задаче именно!
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Можно. этот вопрос обсуждался в другой теме, в сообщениях 17 и 18. Однако это ни к чему не приведет. Тут только 2 выхода:
- extended и приближенные вычисления
- или свои функции на assembler, и своя собственная арифметика (не та, которую поддерживает компилятор pascal)
Третьего не дано.
baranker
Сообщения: 13
Зарегистрирован: 14 дек 2008, 22:54

Esgal, напиши пожалуйста ,если это возможно промежуточный вывод вычислений твоих функций!
т.е. первый факториал =... второй факториал равен ..
и с возведением в степень тоже если можно
unction fact(n:integer):longint;
begin
if n=1 then
begin
fact:=1;
exit;
end;
fact:=fact(n-1)*n;
end;
вычислить по такому (хотя бы) алгоритмы вместо функциии exp заранее благодарен!
Аватара пользователя
Naeel Maqsudov
Сообщения: 2570
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

Вот окончательный вариант (!!! для Turbo Pascal не ниже 5.0).

Код: Выделить всё

program SumSP;
var x:real;
y:extended;
i:byte;


function fact(n:integer):extended;
begin
  if n=1 then begin fact:=1; exit; end;
  fact:=fact(n-1)*n;
end;

function degree(bas:real;deg:longint):extended;
var
  t:extended;
  i:longint;
begin
  t:=1;
  for i:=1 to deg do t:=t*bas; {writeln(t);}
  degree:=t;
end;

function fx(z:real;m:byte):extended;
var
  r,s:extended;
begin
  s:=fact(2*m+1);
  r:=degree(z,2*m-2)/s;

  writeln('fact(',2*m+1,')=',s);
  writeln('fx(',z,',',m,')=',r);

  fx:=r;
end;

begin
  write('input X:'); readln(x);
  y:=0;
  for i:=2 to 14 do y:=y+fx(x,i);
  writeln('summa = ',y:3:5);
  readln;
end.
Проблема была в том, что
1) по условию задачи под факториалом оказывается число 29!
2) В Pascal ABC самый длинный тип - longint
3) В типе longint 12! приводит к переполнению

Поэтому на Pascal ABC задача просто неразрешима.
Аватара пользователя
demon416
Сообщения: 178
Зарегистрирован: 30 янв 2006, 14:03
Откуда: kirovskoe

есть и третий вариант задача разрешима если пользоваться "длинной математикой"
надо все числа представить в виде строк и работать с ними в таком виде тогда нет ограничений на размер чисел
ака хинт: коментируйте код, самим же легче будет разобраться ;)
Ответить