![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
TarasBer |
![]()
Сообщение
#21
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> пока никто не показал окончательный код, который не будет вылетать при eps = 1E-8
А там слишком много итераций уже надо. Стека не хватит. А "код, который не будет вылетать" я показать могу, но он не будет соответствовать требованию делать через [s]жо[s/]рекурсию. -------------------- |
volvo |
![]()
Сообщение
#22
|
Гость ![]() |
Цитата А там слишком много итераций уже надо. Стека не хватит. Ответ неверный... Для 1E-8 - вычисляется рекурсивно, ничего не вылетает. Если твой код, написанный через В общем, все ясно... Причину не ищем, пытаемся побороть следствие... Успехов. |
Client |
![]()
Сообщение
#23
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 865 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
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 из функции в надажде что будет экономиться место (ведь с каждым вхождением для нее выделяется память в стеке?) и добавил счетчик (для тестирования ![]() ![]() Добавлено через 7 мин. хм, 16кб за 1321 итерацию... 1321 раз выделяется память для самой функции (real - 6 байт) и лок. переменной x (integer - 2 байта). 1321*(6+2)=10568. А еще где ~5кб? уходят на вычисление 1.0/(x*(x+2.0))
?Эскизы прикрепленных изображений ![]() ![]() |
Krjuger |
![]()
Сообщение
#24
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Volvo,а разве я не высказал причину,ты бы хоть прокоментировал,верно ли, или не совсем,или же совсем не верно.
|
Lapp |
![]()
Сообщение
#25
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Получилось так. Терерь проблема со стеком. Client, извини, но у тебя проблема не со стеком... ![]() ![]() Добавлено через 7 мин. при этом есть тип Short, который может содержать целые числа о -32,768 до 32,767.Принципи вот из-за этого и происходит переполнение,но для мен лично небольшая загадка почему именно тип short береться для выполнения операций,а не сам integer. Krjuger, ты извини, но ты так туманно выразился, что причину в твоих словах отыскать я так и не смог. Типа short в TP нет. Есть тип shortint размером в 1 байт. А тип integer как раз и есть 2 байта, от -32К до +32К. Для того, чтоб не было вылетов по целым и по флоат, нужно правильно приводить типы. А причина останова в правильно реализованном алгоритме - это все-таки переполнение стека. И происходит оно в ТР при де... ой, чуть не проболтался! )) -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Client |
![]()
Сообщение
#26
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 865 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
убрал свои модификации, оставил как сделал 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(r));
Memo1.Lines.Add('Кол-во итераций: ' + inttostr(i)+ ' eps= '+FloatToStr(eps));
Memo1.Lines.Add(' ');
eps:=eps/10;
end;
end;
Моя ошибка была в добалении переменной и результат был не правильным. Но хотя если заменить выражение переменной, измений быть не должно. Видимо при возвращении функции результата вместо бывшей x1 подставлялось самое последнее значение вместо текущего (т.е. на каждой итерации свое значение)? (в этой стоке)
else f:=x1 + f(x+4);
Хм, на Delphi вроде работает. Теперь паскаль ![]() 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, потом стек переполняется).Эскизы прикрепленных изображений ![]() ![]() |
Rian |
![]()
Сообщение
#27
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 394 Пол: Мужской Репутация: ![]() ![]() ![]() |
если дописать
uses crt,memory; этот алгоритм рассчитает 1е-8 но не больше))) -------------------- Objective-C, Unity3d
|
volvo |
![]()
Сообщение
#28
|
Гость ![]() |
Цитата если дописать Ложь:uses crt,memory; этот алгоритм рассчитает 1е-8 ![]() Кроме того: пока никто не показал окончательный код, который не будет вылетать при eps = 1E-8 независимо от настроек компилятора Турбо-Паскаля. То есть, независимо от того, выбран у меня режим эмуляции сопроцессора или режим 8087/80287... ![]() "Пилите, Шура, пилите..." (С) |
Rian |
![]()
Сообщение
#29
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 394 Пол: Мужской Репутация: ![]() ![]() ![]() |
Эскизы прикрепленных изображений ![]() -------------------- Objective-C, Unity3d
|
volvo |
![]()
Сообщение
#30
|
Гость ![]() |
А я говорю - ложь... Вот мои настройки:
![]() Нечисто играешь, я тебе не разрешал настраивать компилятор, а ты это сделал... По умолчанию (и у меня именно такие установки) размер стека = 16384, ты его изменил, и хочешь мне доказать, что это сделалось подключением модуля Memory? А ты хотя бы его исходники-то видел, умник? Что такого изменилось, что после простого подключения модуля стек вдруг стал больше? Что происходит при подключении этого модуля, ты вообще знаешь? Повторяю еще раз: я не хочу лазить в настройки и менять там что-то. Я хочу увидеть программу, которую я могу у себя откомпилировать (возможно даже консольным компилятором), запустить и посмотреть результат. Это понятно? А то смеяться над чужими программами-то ты умеешь, видели. А вот свое написать (да еще какое - простейшее, работа с вещественными числами) тебе, как выяснилось, не по силам? |
Rian |
![]()
Сообщение
#31
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 394 Пол: Мужской Репутация: ![]() ![]() ![]() |
ну говорилось про процессор ... а про память ничего ![]() ну а про memory ![]() -------------------- Objective-C, Unity3d
|
Client |
![]()
Сообщение
#32
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 865 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
{$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 работает с обычными настройками ![]() |
Rian |
![]()
Сообщение
#33
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 394 Пол: Мужской Репутация: ![]() ![]() ![]() |
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 - 19.02.2010 15:18 -------------------- Objective-C, Unity3d
|
TarasBer |
![]()
Сообщение
#34
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Костыль.
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К надо ещё костылей повбивать. -------------------- |
Rian |
![]()
Сообщение
#35
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 394 Пол: Мужской Репутация: ![]() ![]() ![]() |
так что ответ можно считать правильным?
Сообщение отредактировано: Rian - 21.02.2010 8:16 -------------------- Objective-C, Unity3d
|
volvo |
![]()
Сообщение
#36
|
Гость ![]() |
Цитата так что ответ можно считать правильным? Твой что-ли? Размечтался:![]() (хотя, в принципе, можешь считать как хочешь; программа которая вылетает с переполнением стека тобой тоже может считаться правильной - это на твое усмотрение) Цитата Костыль. Вот именно, что костыль...В общем, ребята, не напрягайтесь, сортируйте массивы и находите в них максимумы дальше, у вас это лучше получается... Всем привет, от темы отписался. Стандартно НЕРАБОТАЮЩИЕ ответы меня больше не интересуют... |
TarasBer |
![]()
Сообщение
#37
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> В общем, ребята, не напрягайтесь, сортируйте массивы и находите в них максимумы дальше, у вас это лучше получается...
Понты... Какое чудо заставит программу, использующую стек размером 16К, которая делает кучу итераций в рекурсии, не проедать стек полностью? Компилятор ТП7 не умеет распознавать подобные рекурсии и разворачивать их в цикл. Можно чисто итераций уменьшить (что я и сделал). А ещё можно руками править регистр стека, сохраняя его содержимое в отдельный файл. Чудес не бывает, вот и всё. -------------------- |
Rian |
![]()
Сообщение
#38
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 394 Пол: Мужской Репутация: ![]() ![]() ![]() |
Твой что-ли? Размечтался: Всем привет, от темы отписался. Стандартно НЕРАБОТАЮЩИЕ ответы меня больше не интересуют... блин... это кто еще не чисто играет? чтобы прога показала переполнение, как это было у тебя на 6 знаках (251) мне пришлось уменьшить стек до 1024 (меньше не делается) ты што на АРИФМОМЕТРЕ компилил??? ![]() PS. правильный ответ в студию! Сообщение отредактировано: Rian - 1.03.2010 17:11 -------------------- Objective-C, Unity3d
|
Гость |
![]()
Сообщение
#39
|
Гость ![]() |
-
|
Jova |
![]()
Сообщение
#40
|
Группа: Пользователи Сообщений: 1 Пол: Мужской Репутация: ![]() ![]() ![]() |
|
![]() ![]() |
![]() |
Текстовая версия | 20.07.2025 0:43 |