IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

2 страниц V < 1 2  
 Ответить  Открыть новую тему 
> Вычислить сумму ряда с заданной точностью с помощью рекурсии, Рекурсия
сообщение
Сообщение #21


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> пока никто не показал окончательный код, который не будет вылетать при eps = 1E-8

А там слишком много итераций уже надо. Стека не хватит.
А "код, который не будет вылетать" я показать могу, но он не будет соответствовать требованию делать через [s]жо[s/]рекурсию.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #22


Гость






Цитата
А там слишком много итераций уже надо. Стека не хватит.
Ответ неверный... Для 1E-8 - вычисляется рекурсивно, ничего не вылетает. Если твой код, написанный через жорекурсию этого сделать не может - это чьи проблемы?

В общем, все ясно... Причину не ищем, пытаемся побороть следствие... Успехов.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #23


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


uses crt;
var
x1:real;
i:integer;
eps:real;

function f(x:integer):real;
begin
inc(i);
x1:=1.0/(x*(x+2.0)); //это и есть неявное приведение типов?
if x1 < eps then f:=0
else f:=x1 + f(x+4);
end;

begin
clrscr;
i:=0;
eps:=0.0000001;
writeln(f(3):0:7);
writeln(i);
readkey
end.
Получилось так. Терерь проблема со стеком. Убрал описание eps из функции в надажде что будет экономиться место (ведь с каждым вхождением для нее выделяется память в стеке?) и добавил счетчик (для тестирования smile.gif) Для 1E-8 происходит переполнение стека. Для 1E-7 работает, вычисляет за 791 итерацию smile.gif

Добавлено через 7 мин.
хм, 16кб за 1321 итерацию...
1321 раз выделяется память для самой функции (real - 6 байт) и лок. переменной x (integer - 2 байта).
1321*(6+2)=10568. А еще где ~5кб? уходят на вычисление
1.0/(x*(x+2.0))
?


Эскизы прикрепленных изображений
Прикрепленное изображение Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #24


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Volvo,а разве я не высказал причину,ты бы хоть прокоментировал,верно ли, или не совсем,или же совсем не верно.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #25


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Client @ 15.02.2010 16:12) *
Получилось так. Терерь проблема со стеком.
Client, извини, но у тебя проблема не со стеком... no1.gif У тебя явная проблема с рекурсией. Твоя программа не будет считать правильно даже при гигабайтном стеке и с прекрасным приведением типов. В ней есть одна очень серьезная ошибка. Давай ты сначала отладишь прогу на FPC или Delphi, а потом уже будешь решать проблемы со стеком на ТР. Хорошо? smile.gif


Добавлено через 7 мин.
Цитата(Krjuger @ 7.02.2010 23:16) *
при этом есть тип Short, который может содержать целые числа о -32,768 до 32,767.Принципи вот из-за этого и происходит переполнение,но для мен лично небольшая загадка почему именно тип short береться для выполнения операций,а не сам integer.
Krjuger, ты извини, но ты так туманно выразился, что причину в твоих словах отыскать я так и не смог.
Типа short в TP нет. Есть тип shortint размером в 1 байт. А тип integer как раз и есть 2 байта, от -32К до +32К. Для того, чтоб не было вылетов по целым и по флоат, нужно правильно приводить типы. А причина останова в правильно реализованном алгоритме - это все-таки переполнение стека. И происходит оно в ТР при де... ой, чуть не проболтался! ))


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #26


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


убрал свои модификации, оставил как сделал volvo с подсчетом итераций, и eps сделал глобальной. Вот как выглядит функция
function f(x:integer):real;
begin
inc(i);
if 1/(1.0* x * (x+2)) < eps then f := 0
else f := (1/(x * (x+2))) + f(x + 4);
end;
и обработчик кнопки
procedure TForm2.Button1Click(Sender: TObject);
var
r:real;
k:byte;
begin
eps:=1E-1;
Memo1.Clear;
for k := 1 to 10 do begin
i:=0;
r:=f(3);
Memo1.Lines.Add(inttostr(k)+ ') ' +FloatToStr®);
Memo1.Lines.Add('Кол-во итераций: ' + inttostr(i)+ ' eps= '+FloatToStr(eps));
Memo1.Lines.Add(' ');
eps:=eps/10;
end;
end;
Моя ошибка была в добалении переменной и результат был не правильным. Но хотя если заменить выражение переменной, измений быть не должно. Видимо при возвращении функции результата вместо бывшей x1 подставлялось самое последнее значение вместо текущего (т.е. на каждой итерации свое значение)? (в этой стоке)
else f:=x1 + f(x+4);

Хм, на Delphi вроде работает. Теперь паскаль smile.gif
uses crt;
var
x1:real;
i,k:integer;
eps:real;

function f(x:integer):real;

begin
inc(i);
if 1/(1.0 * x * (x+2)) < eps then f := 0
else f := (1/(1.0 * x * (x+2))) + f(x + 4);
end;

begin
clrscr;
i:=0;
eps:=1E-1;
for k:=1 to 7 do begin
i:=0;
writeln(f(3):0:7, ' ',i);
eps:=eps/10;
end;
readkey
end.
Выдает такие же значения (до 1Е-7, потом стек переполняется).


Эскизы прикрепленных изображений
Прикрепленное изображение Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #27


Знаток
****

Группа: Пользователи
Сообщений: 396
Пол: Мужской

Репутация: -  9  +


если дописать
uses crt,memory;

этот алгоритм рассчитает 1е-8
но не больше)))


--------------------
Objective-C, Unity3d
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #28


Гость






Цитата
если дописать
uses crt,memory;

этот алгоритм рассчитает 1е-8
Ложь:
Прикрепленное изображение

Кроме того:
Цитата(volvo @ 7.02.2010 22:03) *

пока никто не показал окончательный код, который не будет вылетать при eps = 1E-8 независимо от настроек компилятора Турбо-Паскаля. То есть, независимо от того, выбран у меня режим эмуляции сопроцессора или режим 8087/80287...
Малейшая попытка задействовать сопроцессор приводит вот к чему:
Прикрепленное изображение

"Пилите, Шура, пилите..." (С)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #29


Знаток
****

Группа: Пользователи
Сообщений: 396
Пол: Мужской

Репутация: -  9  +


Цитата(volvo @ 19.02.2010 12:12) *

Ложь:

правда


Эскизы прикрепленных изображений
Прикрепленное изображение

--------------------
Objective-C, Unity3d
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #30


Гость






А я говорю - ложь... Вот мои настройки:
Прикрепленное изображение

Нечисто играешь, я тебе не разрешал настраивать компилятор, а ты это сделал... По умолчанию (и у меня именно такие установки) размер стека = 16384, ты его изменил, и хочешь мне доказать, что это сделалось подключением модуля Memory? А ты хотя бы его исходники-то видел, умник? Что такого изменилось, что после простого подключения модуля стек вдруг стал больше? Что происходит при подключении этого модуля, ты вообще знаешь?

Повторяю еще раз: я не хочу лазить в настройки и менять там что-то. Я хочу увидеть программу, которую я могу у себя откомпилировать (возможно даже консольным компилятором), запустить и посмотреть результат. Это понятно? А то смеяться над чужими программами-то ты умеешь, видели. А вот свое написать (да еще какое - простейшее, работа с вещественными числами) тебе, как выяснилось, не по силам?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #31


Знаток
****

Группа: Пользователи
Сообщений: 396
Пол: Мужской

Репутация: -  9  +


Цитата(volvo @ 19.02.2010 12:28) *

А я говорю - ложь... Вот мои настройки:
Прикрепленное изображение

ну говорилось про процессор ...
а про память ничего wink.gif
ну а про memory smile.gif че б голову не поморочить


--------------------
Objective-C, Unity3d
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #32


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


{$S-}
uses crt;
var
x1:real;
i,k:integer;
eps:real;

function f(x:integer):real;

begin
inc(i);
if 1/(1.0 * x * (x+2)) < eps then f := 0
else f := (1/(1.0* x * (x+2))) + f(x + 4);
end;

begin
clrscr;
i:=0;
eps:=1E-1;
for k:=1 to 8 do begin
i:=0;
writeln(f(3):0:7,' ',eps, ' ',i);
eps:=eps/10;
end;
readkey
end.
Фишка в директиве {$S-} ? 1Е-8 работает с обычными настройками smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #33


Знаток
****

Группа: Пользователи
Сообщений: 396
Пол: Мужской

Репутация: -  9  +



uses crt;
var
x1,s:real;
i,k:integer;
eps:real;
z:boolean;

procedure f(x:word);
begin
inc(i);

if 1/(1.0*x * (x+2)) < eps then

else begin
s :=s+1/(1.0*x * (x+2));
f(x+4);
end;
end;

begin
clrscr;
eps:=1E-1;
for k:=1 to 8 do begin
i:=0;
s:=0;
f(3);
writeln(s:0:7, ' ',i,' ',eps);
eps:=eps/10;
end;
readkey
end.


Сообщение отредактировано: feniks25 -


--------------------
Objective-C, Unity3d
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #34


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Костыль.


function f(X: longint; eps: real): real;
var
r, rf: real;
begin
r := 1/(longint(x+0)*(x+2))
+ 1/(longint(x+4)*(x+6))
+ 1/(longint(x+8)*(x+10))
+ 1/(longint(x+12)*(x+14));
if (r - 4*eps < 0) then r := 0
else begin
rf := f(x + 16, eps);
r := r + rf;
end;
f := r;
end;



Для стека 65536 и епсилон 1е-8 это работает, да. Для стека 16К надо ещё костылей повбивать.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #35


Знаток
****

Группа: Пользователи
Сообщений: 396
Пол: Мужской

Репутация: -  9  +


так что ответ можно считать правильным?

Сообщение отредактировано: Rian -


--------------------
Objective-C, Unity3d
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #36


Гость






Цитата
так что ответ можно считать правильным?
Твой что-ли? Размечтался:
Прикрепленное изображение
(хотя, в принципе, можешь считать как хочешь; программа которая вылетает с переполнением стека тобой тоже может считаться правильной - это на твое усмотрение)

Цитата
Костыль.
Вот именно, что костыль...

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

Всем привет, от темы отписался. Стандартно НЕРАБОТАЮЩИЕ ответы меня больше не интересуют...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #37


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> В общем, ребята, не напрягайтесь, сортируйте массивы и находите в них максимумы дальше, у вас это лучше получается...

Понты...
Какое чудо заставит программу, использующую стек размером 16К, которая делает кучу итераций в рекурсии, не проедать стек полностью? Компилятор ТП7 не умеет распознавать подобные рекурсии и разворачивать их в цикл.
Можно чисто итераций уменьшить (что я и сделал). А ещё можно руками править регистр стека, сохраняя его содержимое в отдельный файл.
Чудес не бывает, вот и всё.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #38


Знаток
****

Группа: Пользователи
Сообщений: 396
Пол: Мужской

Репутация: -  9  +


Цитата(volvo @ 25.02.2010 13:44) *

Твой что-ли? Размечтался:
Всем привет, от темы отписался. Стандартно НЕРАБОТАЮЩИЕ ответы меня больше не интересуют...

блин... это кто еще не чисто играет?
чтобы прога показала переполнение, как это было у тебя на 6 знаках (251) мне пришлось уменьшить стек до 1024 (меньше не делается)

ты што на АРИФМОМЕТРЕ компилил??? lol.gif

PS. правильный ответ в студию!

Сообщение отредактировано: Rian -


--------------------
Objective-C, Unity3d
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #39


Гость






-
 К началу страницы 
+ Ответить 
сообщение
Сообщение #40





Группа: Пользователи
Сообщений: 1
Пол: Мужской

Репутация: -  0  +


Цитата(volvo @ 25.02.2010 13:44) *

Цитата
так что ответ можно считать правильным?

Твой что-ли? Размечтался:


А не поторопился ?
Решение Rian у меня работает. Нет переполнения стека

Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V < 1 2
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 30.04.2024 10:17
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name