Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Количество знаков после запятой. Разные результаты при одинаковых значениях. / 9 сообщений из 9, страница 1 из 1
06.06.2020, 11:59
    #39966717
Ученик_333
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Добрый день, для сокращения количества знаков, после запятой пользуюсь таким способом:
Код: pascal
1.
degree1 := trunc(degree1*100)*0.01; // Не больше 2 знаков после запятой


Подскажите пожалуйста, почему приведенный ниже код, в не измененном состоянии, показывает сообщение: " Точка не образует угол ", но после раскомментирования строк " //degree1,//degree2 ", показывает уже другое?
Ведь все значения " degree " в обоих случаях одинаковы.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
uses Math;

procedure TForm1.Button1Click(Sender: TObject);
var
Xp,Yp,Xa,Ya,Xb,Yb:integer;
NumberOfSymbols0,NumberOfSymbols1,
degree0,degree1,degree2,degreeDirection,Deg1:extended;
begin
 NumberOfSymbols0 := Power(0.1, 12); // Для ограничения чисел до 12 знаков после запятой
 NumberOfSymbols1 := Power(10, 12);

   // Точка многоугольника
   Xp := 221;
   Yp := 275;

   // Предыдущая точка многоугольника
   Xa := 86;
   Ya := 275;

   // Следующая точка многоугольника
   Xb := 337;
   Yb := 275;

   degreeDirection := -90;


     degree1 := ArcTan2(Yp-Ya,Xa-Xp)/pi*180;
     //degree1 := trunc(degree1*NumberOfSymbols1)*NumberOfSymbols0; // Не больше 12 знаков после запятой
     if degree1<0 then degree1 := 360+degree1; // Направление отрезка 1


     degree2 := ArcTan2(Yp-Yb,Xb-Xp)/pi*180;
     //degree2 := trunc(degree2*NumberOfSymbols1)*NumberOfSymbols0; // Не больше 12 знаков после запятой
     if degree2<0 then degree2 := 360+degree2; // Направление отрезка 2


     if (degree1<degree2) then Deg1:=0 else Deg1:=360;
     degree0 := (degree2+Deg1)-degree1; // Размер угла

     if (degree0<=180) then Deg1:=0 else Deg1:=360;
     degree0:=degree0-Deg1; // + = По часовой, - = Против часовой


    if (abs(degree0)=180) then // Если точка не образует угол
    begin
     showmessage('Точка не образует угол'
     +#13#10+#13#10+'Угол между отрезками: '+floattostr(degree0)
     +#13#10+'Направления отрезков: '+floattostr(degree1)+' ; '+floattostr(degree2));
    end
    else
    if (((degreeDirection<0) and (degree0<0))
     or ((degreeDirection>=0) and (degree0>=0))) then // Направления углов совпадают, значит это выпуклый угол (Размер угла внутри многоугольника (0..180))
    begin
     showmessage('Выпуклый угол'
     +#13#10+#13#10+'Угол между отрезками: '+floattostr(degree0)
     +#13#10+'Направления отрезков: '+floattostr(degree1)+' ; '+floattostr(degree2));
    end
    else // Направления углов не совпадают, значит это впуклый угол (Размер угла внутри многоугольника (180..360))
    begin
     showmessage('Впуклый угол'
     +#13#10+#13#10+'Угол между отрезками: '+floattostr(degree0)
     +#13#10+'Направления отрезков: '+floattostr(degree1)+' ; '+floattostr(degree2));
    end;
end;


Про функцию "FormatFloat('0.####', float)" знаю, просто в условиях "if (...) then" у меня много значений и код получается очень большим.
В другом коде была ошибка приведенная ниже, где с этим способом все работает нормально.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure TForm1.Button2Click(Sender: TObject);
var
NumberOfSymbols0,NumberOfSymbols1,
t,l:extended;
begin
 NumberOfSymbols0 := Power(0.1, 12); // Для ограничения чисел до 12 знаков после запятой
 NumberOfSymbols1 := Power(10, 12);

 t := 0.540540540540541;
 l := Sqrt(Sqr(160-160+(160-160)*t)+Sqr(78-118+(152-78)*t));
 //l := trunc(l*NumberOfSymbols1)*NumberOfSymbols0; // Не больше 12 знаков после запятой

 if (l=0) then
  showmessage('l=0:    '+floattostr(l))
 else showmessage('l>0:    '+floattostr(l));
end;

...
Рейтинг: 0 / 0
06.06.2020, 12:29
    #39966720
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Никогда нельзя сравнивать вещественные числа на равенство.

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374
...
Рейтинг: 0 / 0
06.06.2020, 20:56
    #39966782
Anton_1234
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
я обычно беру разность значений и если она по модуля меньше какого-то числа, скажем 1Е-7, то считаю числа равными
т.е
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
if abs(a-b)<1E-7
then ShowMessage('a=b')
esle ShowMessage('a<>b');
//можно и функцию написать, а может уже и есть типа такой
function Ravno(AValue1, AValue2, ATochnost:double):Boolean;
begin
  if abs(AValue1-AValue2)<ATochnost
  then Result:=True
  else Result:=False;
end;
// а если ATochnost будет меньше нуля? а... скажет что числа не равны



это еще хорошо если числа все из дельфи берутся, а если одно из Excel, второе из базы какой-нибудь, дельфи их забирает и внутри у себя сравнивает, тогда вообще капец
...
Рейтинг: 0 / 0
06.06.2020, 21:13
    #39966784
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Недавно обсуждалось.
Есть функции сравнения (для каждого типа - со своим эпсилоном, или можно передать) - SameValue и другие в модуле Math.
...
Рейтинг: 0 / 0
07.06.2020, 13:09
    #39966838
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Anton_1234
Код: pascal
1.
2.
3.
  if abs(AValue1-AValue2)<ATochnost
  then Result:=True
  else Result:=False;


/facepalm
...
Рейтинг: 0 / 0
07.06.2020, 13:17
    #39966840
Ученик_333
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Спасибо за подсказки. В моем случае, иногда нужно переводить код на другой язык, поэтому решил пока остановиться на этом варианте.
Код: pascal
1.
    if (abs( abs(degree0)-180 )<0.0001) then // Если точка не образует угол
...
Рейтинг: 0 / 0
07.06.2020, 13:23
    #39966843
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Ученик_333решил пока остановиться на этом варианте.

Лучше бы ты векторной алгеброй воспользовался. Там можно считать без потери точности.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
07.06.2020, 13:33
    #39966845
Ученик_333
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Dimitry Sibiryakov
Лучше бы ты векторной алгеброй воспользовался. Там можно считать без потери точности.
Хорошо, учту.
...
Рейтинг: 0 / 0
09.06.2020, 09:10
    #39967264
Beltar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Количество знаков после запятой. Разные результаты при одинаковых значениях.
Сокращать знаки надо только при выводе в виде текста. Проще всего, наверное, RoundTo(X,-2), если нужно 2 знака оставить. В остальных случаях принять желаемую точность машинного нуля.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Количество знаков после запятой. Разные результаты при одинаковых значениях. / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]