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

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

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

> Проблемы в Pascal (для всех компиляторов!)
сообщение
Сообщение #1





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

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


Программу одну составил по олимпиадным задачам. Суть задачи состоит в том, что нужно узнать по данным координатам, находится ли точка в треугольнике. Я сравниваю площадь треугольника и площадь четырехугольника (получившегося из соединения линиями треугольника с точкой) с помощью функции round(). Но, когда она [функция] округляет 4.5 два раза, то сначала получается 5, а потом 4. Что делать? Не хотелось бы менять весь алгоритм из-за какой-то ошибки в компиляторах (кстати, я проверял и на PascalABC, и на TurboPascal, и на FreePascal).
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 8)
сообщение
Сообщение #2


Гуру
*****

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

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


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

Кстати, подозреваю, что и реализованный алгоритм также не дает правильного ответа на поставленный вопрос.
Зачем, кстати, ты округляешь?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3





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

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


знаешь формулу для нахождения площади фигуры по координатам? вот она: s=s+sqrt(p*(p-a)*(p-b)*(p-c), где
p=(a+b+c)/2, a=sqrt((x[1]-x[i])^2+(y[1]-y[i])^2),b=sqrt((x[i]-x[i+1])^2+(y[i]-y[i+1])^2),c=sqrt((x[i+1]-x[1])^2+(y[i+1]-y[1])^2), 2<=i<=n-1. Так мы находим площадь треугольника, а чтобы найти площадь фигуры "треугольник+точка", просто меняем x[1] и y[1] на xx и yy (координаты точки), x[n+1]=x[1],y[n+1]=y[1],1<=i<=n. Получается два вещественных числа, которые надо округлить, потому что без округления числа не равны в любом случае (кстати, почему???), округляем. На первых тестах все проходит, но следущих тестах одинаковые площади двух фигур (допустим, 4.5 и 4.5) округляются по разному - 5 и 4. А без округления они не равны. В чем же глюк??
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






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





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

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



var
input,output:text;
x,y:array[1..4]of integer;
i,n,xx,yy:integer;
a,b,c,p,s1,s2:real;
begin
assign(input,'tria-pt.in');
assign(output,'tria-pt.out');
reset(input);
rewrite(output);
n:=3;
i:=1;
while i<=n do
begin
readln(input,x[i],y[i]);
i:=i+1;
end;
readln(input,xx,yy);
a:=sqrt(sqr(x[1]-x[2])+sqr(y[1]-y[2]));
b:=sqrt(sqr(x[2]-x[3])+sqr(y[2]-y[3]));
c:=sqrt(sqr(x[3]-x[1])+sqr(y[3]-y[1]));
p:=(a+b+c)/2;
s1:=sqrt(p*(p-a)*(p-b)*(p-c));
x[n+1]:=x[1];
y[n+1]:=y[1];
i:=1;
while i<=n do
begin
a:=sqrt(sqr(xx-x[i])+sqr(yy-y[i]));
b:=sqrt(sqr(x[i]-x[i+1])+sqr(y[i]-y[i+1]));
c:=sqrt(sqr(x[i+1]-xx)+sqr(y[i+1]-yy));
p:=(a+b+c)/2;
s2:=s2+sqrt(p*(p-a)*(p-b)*(p-c));
i:=i+1;
end;
if round(s1)=round(s2) then
writeln(output,'In')
else
writeln(output,'Out');
close(input);
close(output);
end.

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


Гость






Ну, и что? Запустил программу под FPC, треугольник: (1, 1), (4, 8), (6, 4) и точка (5, 6). S1 = S2, выдало ответ "In", что я делаю не так? Значит, проблема не в компиляторе? С какими значениями у тебя неверный ответ?

P.S. Прочитай уже, что тебе написали выше: выброси Round и сравнивай s1 и s2 как и положено сравнивать вещественные числа, с какой-то погрешностью: Abs(s1 - s2) < eps
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7





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

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


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


Гость






Цитата
-2 -2
3 1
0 1
0 1
И с этими значениями проходит равенство, и выдает In (и FPC 2.2.4, и Турбо-Паскаль 7 со включенным сопроцессором. Без сопроцессора Round работает чуть по-другому и результат иной)...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9





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

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


Спасибо, действительно, разница помогла. Вот код:

program triapt;
var
input,output:text;
x,y:array[1..4]of integer;
i,n,xx,yy:integer;
a,b,c,p,s1,s2:real;
begin
assign(input,'tria-pt.in');
assign(output,'tria-pt.out');
reset(input);
rewrite(output);
n:=3;
i:=1;
while i<=n do
begin
readln(input,x[i],y[i]);
i:=i+1;
end;
readln(input,xx,yy);
a:=sqrt(sqr(x[1]-x[2])+sqr(y[1]-y[2]));
b:=sqrt(sqr(x[2]-x[3])+sqr(y[2]-y[3]));
c:=sqrt(sqr(x[3]-x[1])+sqr(y[3]-y[1]));
p:=(a+b+c)/2;
s1:=sqrt(p*(p-a)*(p-b)*(p-c));
x[n+1]:=x[1];
y[n+1]:=y[1];
i:=1;
while i<=n do
begin
a:=sqrt(sqr(xx-x[i])+sqr(yy-y[i]));
b:=sqrt(sqr(x[i]-x[i+1])+sqr(y[i]-y[i+1]));
c:=sqrt(sqr(x[i+1]-xx)+sqr(y[i+1]-yy));
p:=(a+b+c)/2;
s2:=s2+sqrt(p*(p-a)*(p-b)*(p-c));
i:=i+1;
end;
if round(abs(s1-s2))=0 then //вот здесь я изменил - и все работает!
writeln(output,'In')
else
writeln(output,'Out');
close(input);
close(output);
end.



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

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

 





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