тяжёлая математическая задача

Модераторы: Duncon, Naeel Maqsudov, Хыиуду, Игорь Акопян

somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

09 окт 2007, 21:41

Необходимо найти сумму ряда с точностью E=10^-3, общий член которого
an:=((2^n)*n!)/((n^n)!)
пробьлемы как в целом с написанием программы так и в деталях: например, задавая цикл для подсчёта факторила (n^n)! здесь задаём n как экспоненту а т.к. это вещ.тип данных то и цикл считать отказывается..неразбериха...ктонибудь знает что делать?
tm2007
Сообщения: 9
Зарегистрирован: 05 окт 2007, 01:43

10 окт 2007, 10:18

Я бы так примерно решил вашу задачу:

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

program math1;

{ф-ция вычисления X^Y (Y больше или равно 0)}
function Rng(X, Y: Integer): Integer;
var
 I, R: Integer;
begin
 R:=1;
 for I:=1 to Y do
  R:=R*X;
 Rng:=R;
end;

{ф-ция вычисления факториала}
function Fctrl(N1: Integer): Integer;
var
 I, F: Integer;
begin
 F:=1;
 for I:=2 to N1 do
  F:=F*I;
 Fctrl:=F;
end;

var
 An, S, E: Real;
 N, C, Z, B: Integer;
begin
 E:=0.001; {погрешность}
 N:=1;
 S:=0; {нач. значение суммы ряда}
 repeat
 {вычисляем числитель в выражении для вычисления значения N-го члена ряда}
  C:=Rng(2, N)*Fctrl(N);
 {вычисляем знаменатель в выражении для вычисления значения N-го члена ряда}
  B:=Rng(N, N);
  Z:=Fctrl(B);
 {вычисляем N-й член ряда}
  An:=C/Z;
  S:=S+An; 
  N:=N+1;
 until An<E; 
 writeln('Summa ryada S=', S:3:3);
 writeln('Kol-vo iteratsii: ', N-1);
 readln;
end.
somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

10 окт 2007, 11:34

tm2007, спасибо большое, у меня одно лишь пожелание: нельзя ли обойтись в этой программе без функции вообще (имею ввиду Rng и Fctrl), а заделать их в саму программу. В этом вся проблема..
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

10 окт 2007, 11:41

&quot писал(а):function Fctrl(N1: Integer): Integer;
var
I, F: Integer;
begin
F:=1;
for I:=2 to N1 do
F:=F*I;
Fctrl:=F;
end;
Я может и не в тему, но было бы отлично, если б функция факториала возращала не Integer, а хотя бы LongInt, ибо факториал - вещь страшная и функция Fctrl(10) врядли вернет правильное значение.
Остальных функций и вычислений это тоже касается. Вы взгляните получше на выражение, там сплошные степени, 1-5 еще проканает, а что будет потом...
It's a long way to the top if you wanna rock'n'roll
tm2007
Сообщения: 9
Зарегистрирован: 05 окт 2007, 01:43

10 окт 2007, 13:26

Совершенно верное замечание. Дело в том, что делал на скорую руку. Хотел использовать как раз LongInt, но, взглянув на выражение, пришел к мысли, что вычисления скорее всего закончатся на 3-й итерации :)
И оказался прав :)
А так, надо использовать LongInt. Тем более, человеку, как понял, задачу надо писать на Турбо-Паскале.
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

10 окт 2007, 13:45

Небольшие подсказки, которые уменьшат код и увеличат точность:

1. 2^n - лучше записать так:

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

x = 1 shl n;
2. Если преобразовать функцию, то
a(n) = 2^n / (n+1, n^n)!
т.е. если даже визуально a(4) = 2^4 * 1*2*3*4 / 1*2*3*4*5*6*...,
то видно, что дробь сводится к a(4) = 2^4 / 5*6*7*8*9*...
Это значительно увеличит точность и уменьшит число итераций.
It's a long way to the top if you wanna rock'n'roll
somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

10 окт 2007, 23:44

не пойму где ошибка но выдаёт 'деление на 0'
если так то только в знам. а значит в функции Rnd, а там вроде и ошибок нет
непонятно даже что исправлять-то
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

11 окт 2007, 08:59

somebody_now, ты вообще посты читаешь. Я ведь говорил, что Integer использовать нельзя, т.к. большие числа выходят. Замени ВЕЗДЕ Integer на Longint и все будет нормально работать
It's a long way to the top if you wanna rock'n'roll
somebody_now
Сообщения: 35
Зарегистрирован: 02 окт 2007, 14:43

11 окт 2007, 10:40

somewhere, читаю конечно))только не всегда вовремя 'осуществляю' их на практике а жаль(
эту прогу надо было отправить преподу до полуночи дня сегодняшнего,а теперь -0.5балла и возможно серьёзные последствия(
tm2007
Сообщения: 9
Зарегистрирован: 05 окт 2007, 01:43

11 окт 2007, 11:36

Если без использования ф-ций, то так пойдет, наверное:

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

program math1;
var
 An, S, E: Real;
 N, R, Z, B, I: LongInt;
begin
 E:=0.001;
 N:=1;
 S:=0;
 repeat
   R:=1;
  for I:=1 to N do
   R:=R*2*I;
   Z:=1;
   for I:=1 to N do
   Z:=Z*N;
  B:=1;
   for I:=1 to Z do
    B:=B*I;
  An:=R/B; 
  S:=S+An; 
  N:=N+1;
 until An<E;
 writeln('Summa ryada S=', S:3:3);
 writeln('Kol-vo iteratsii: ', N-1);
 readln;
end.
Писал на Delphi 7. В Delphi 7 тип Integer имеет размер 4 байта, то есть всего может быть 2^32 значений (диапазон значений -2147483648..2147483647).
В Турбо-Паскале тип Integer имеет размер 2 байта, то есть всего может быть 2^16 значений (диапазон значений -32768..32767).
Вычисления заканчиваются при N=3.
При N=3 значение знаменателя в выражении: (N^N)!=(3^3)!=27!
27! - это огромное число, равное 1484783616.
Оно выходит за пределы диапазона значений для типа Integer в Турбо-Паскале, для хранения этого числа двух байтов будет недостаточно.
Поэтому надо использовать тип LongInt (длинный Integer), который в Турбо-Паскале имеет размер 4 байта.
В Delphi 7 типы Integer и IntLong имеют одинаковую размерность, равную 4 байтам.
А так, вам вчера Somewhere совершенно верно подсказал, что надо использовать тип LongInt. Везде бы заменили Integer на LongInt, и все было бы в порядке :)
Ответить