Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 21.10.2017, 18:51
Pan4ick Pan4ick вне форума
Прохожий
 
Регистрация: 21.10.2017
Сообщения: 2
Версия Delphi: Delphi 7
Репутация: 10
Злость Условие работает неправильно

Почему если я сравниваю y в операторе if с целым числом(например с 1), то все работает и в форме выводится "условие не выполняется" если ввести 1, но если y сравнивается с дробным числом(как в данном случае 1.2), то условие игнорируется и даже при введении в edit2 числа 1.2 условие идет дальше и мне выводится ответ. Как это исправить?
Код:
procedure TForm1.Button1Click(Sender: TObject);
var x,y,a,b,U:real;
begin
x:=strtofloat(Edit1.Text);
y:=strtofloat(Edit2.Text);
if (y<>1.2) and (sin(x)+cos(y)<>0) then
begin
a:=exp(-power(x,2)+1)+sin(power(x,2)-8)/(1.2-y);
b:=sqrt(abs(y-2))+(2*power(x,2)-6*x-1)/(sin(x)+cos(y));
if a>b then U:=a
else U:=b;
label1.Caption:='U='+format('%9.4f',[u]);
end
   else
       label1.Caption:='Условие не выполняется'
end;

end.
Админ: Пользуемся тегами при оформлении кода!

Последний раз редактировалось Admin, 21.10.2017 в 19:06.
Ответить с цитированием
  #2  
Старый 21.10.2017, 21:07
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от Pan4ick
Почему если я сравниваю y в операторе if с целым числом(например с 1), то все работает и в форме выводится "условие не выполняется" если ввести 1, но если y сравнивается с дробным числом(как в данном случае 1.2), то условие игнорируется и даже при введении в edit2 числа 1.2 условие идет дальше и мне выводится ответ. Как это исправить?
Код:
procedure TForm1.Button1Click(Sender: TObject);
var x,y,a,b,U:real;
begin
x:=strtofloat(Edit1.Text);
y:=strtofloat(Edit2.Text);
if (y<>1.2) and (sin(x)+cos(y)<>0) then
begin
a:=exp(-power(x,2)+1)+sin(power(x,2)-8)/(1.2-y);
b:=sqrt(abs(y-2))+(2*power(x,2)-6*x-1)/(sin(x)+cos(y));
if a>b then U:=a
else U:=b;
label1.Caption:='U='+format('%9.4f',[u]);
end
   else
       label1.Caption:='Условие не выполняется'
end;

end.
Админ: Пользуемся тегами при оформлении кода!
Эта ситуация уже очень много раз обсуждалась.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #3  
Старый 22.10.2017, 01:33
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от NumLock
Эта ситуация уже очень много раз обсуждалась.

Нам, хотя бы в кратце можно и повторить.
В общем случае сравнение чисел с плавающей точкой это не точная операци, т.к. в силу представления чисел внутри компьютера 1 может быть не равно 1, т.к. реальное значение в зависимости от вычисления будет действительно не равно:
Код:
0.9999999999999 <> 1.000000000001
В примере, эти два числа не равны друг другу, но в силу округления тебе оба они выводяться как "1".
Соотвественно, решением проблемы может быть:
1. Перевод в целое или дробное с фиксированной точкой
2. Сравнение через Epsilon (т.е. с указанной точностью)
Например, в первом случае либо переводим в тип Currency (как пример) или, если мы уверены в порядке значения, то в Integer, умножая значение на, например, 1000.
Для второго случая, определем эпсилон и сравниваем разницу:
Код:
const
  epsilon = 0.000001;
...
  if abs(abs(y)-1.2) < epsilon then label1.caption := 'y = 1.2' else label1.caption := 'y <> 1.2';
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Pan4ick (22.10.2017)
  #4  
Старый 22.10.2017, 13:13
Pan4ick Pan4ick вне форума
Прохожий
 
Регистрация: 21.10.2017
Сообщения: 2
Версия Delphi: Delphi 7
Репутация: 10
Радость

Спасибо за помощь, поменял тип на currency, все работает)
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:51.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter