Помощь - Поиск - Пользователи - Календарь
Полная версия: Разветвляющаяся программа.
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Russel
Разветвляющаяся программа. Работа с числами. Предусмотреть при одном запуске программы на выполнение расчёт по нескольким наборам исходных данных. Подготовить отладочные просчёты и схему алгоритма.
Даны a, b, c.
Определить, является ли одно из них гипотенузой прямоуголь¬ного треугольника со сторонами a, b, c. Вывести соот¬ветствующее сообщение.

program lab2;
uses crt;
var a,b,c:real;
begin clrscr;
writeln ('vvedite znacheniya');
read (a,b,c);
if (sqr (a)+sqr(b)=sqr©) or (sqr(b)+sqr©=sqr(a)) or (sqr(a)+sqr©=sqr(b)) then writeln ('gipotenuza')
else writeln ('ne yavlyaetsya');
end.


Как здесь написать, чтобы все три условия работали? Чтоб выводилось "гипотенуза a" гипотенуза b ,с...

Спасибо!
Lapp
Можно вот так, например:
a2:=a*a;
b2:=b*b;
c2:=c*c;
if Abs(c2+b2-a2)<e then WriteLn('gipotenuza a')
else if Abs(a2+c2-b2)<e then WriteLn('gipotenuza b')
else if Abs(a2+b2-c2)<e then WriteLn('gipotenuza c')
else writeln ('ne yavlyaetsya');

Я ввел дополнительные переменные для ускорения расчетов и удобочитаемости.
Число e - это точность. Действительные числа нельзя сравнивать равенством. Положи e равным числу, малому по сравнению с a, b и с. Типа если они порядка единицы, то е можно взять типа 1e-7.
Russel
program lab2;
uses crt;
var a,b,c:real;
begin clrscr;
writeln ('vvedite znacheniya');
read (a,b,c);
if sqr (a)+sqr(b)=sqr© then writeln ('gipotenuza C')
else if sqr(a)+sqr©=sqr(b) then writeln ('gipotenuza B')
else if sqr(b)+sqr©=sqr(a) then writeln ('gipotenuza A')
else writeln ('ne yavlyaetsya');
end.


А так? И критичен ли тип переменных? Для контр. просчета взял числа 3, 4, 5 в разных комбинациях. Вроде работает.
Lapp
Цитата(Russel @ 17.12.2008 21:03) *
критичен ли тип переменных? Для контр. просчета взял числа 3, 4, 5 в разных комбинациях. Вроде работает.
Хорошо, давай разберемся.
Ты согласен, что треугольник, подобный данному прямоугольному, тоже прямоугольный?
Теперь смотри, что получается.
Сначала я задаю числа 3, 4 и 5. Вот результат:
vvedite znacheniya
3 4 5
gipotenuza C

Все правильно, да?
А теперь задаю 3.3, 4.4 и 5.5 (получаются умножением на 1.1)
vvedite znacheniya
3.3 4.4 5.5
ne yavlyaetsya

Как видишь, результат неверный.
Почему?.. Давай разберемся.
Я вставил в код печать разности (a^2+b^2) - c^2 .
var
a,b,c:real;

begin
clrscr;
writeln ('vvedite znacheniya');
read (a,b,c);
if sqr (a)+sqr(b)=sqr© then writeln ('gipotenuza C')
else if sqr(a)+sqr©=sqr(b) then writeln ('gipotenuza B')
else if sqr(b)+sqr©=sqr(a) then writeln ('gipotenuza A')
else writeln ('ne yavlyaetsya');
WriteLn('Discrepancy: ',Sqr(a)+Sqr(b)-Sqr( c)); { вставлена печать разности }
end.

По идее, эта разность должна быть нулем, верно? Но реально выходит вот, что:
vvedite znacheniya
3.3 4.4 5.5
ne yavlyaetsya
Discrepancy: 1.953298633949885E-015

Разница очень маленькая (0,00000000000000195.. - это порядка неточности в одну десятую миллиметра на расстоянии от Земли до Солнца smile.gif), но она есть. Это ошибка машинных вычислений. И именно она мешает осуществиться твоему равенству.

Теперь понятно, почему нельзя действительные числа сравнивать простым равенством? smile.gif
Машинные ошибки - это абсолютно неизбежный побочный эффект при компьютерных вычислениях в действительных числах. Всегда необходимо помнить, что все вычисления проводятся с некоторой точностью, и учитывать это в задачах.

P.S.
Результат (неточность вычислений) может отличаться на разных компьютерах и для разных компиляторов, но суть остается той же. Если у тебя не получилось повторить мои результаты с числами 3.3, 4.4 и 5.5 - попробуй другие. Типа 3.33, 4.44 и 5.55 smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.