Ошибка в работе оператора if при сравнении чисел типа double - страница 2

 
olyakish:
Вообще бы неплохо получить комментарии к моему последнему посту о умножении на 100000000 и о результатах всего этого

Посмотрите ветки на эту тему - https://www.mql4.com/ru/search/?keyword=CompareDoubles+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5&period=0&author=

 
Резюме

Все разговоры до этого сводятся к тому что есть хвосты "далеко" от запятой.

Но в моем случае таких хвостов нет. ТК я умножением на 100000000 вывел все числа после запятой на Print и могу глазками сказать\утверждать о отсутсвии "мусора" в этих двух числах

По этому я считаю что это все же ошибка.

Но есть варианты как эту ошибку обойти. На этом спасибо.

 
Можно сделать так:

datetime t1=cTime1,t2=cTime2;
int cc1,cc2,co1,co2;
cc1=MathRound(cCena1/Point);
cc2=MathRound(cCena2/Point);
int j=iBarShift(Symbol(),tf,cTime1,false), k=iBarShift(Symbol(),tf,cTime2,false);

// Проверка High
co1=MathRound(iHigh(Symbol(),tf,j)/Point);
co2=MathRound(iHigh(Symbol(),tf,k)/Point);

if (co1==cc1 && co2==cc2)
{
}

 
Алексей, я чё-та не понимаю, Вам ехать или шашечки? Если ехать, то нормализуйте. И не надо никаких премудростей. Просто - надёжно! То, что Вы придумаете умножением и прочими хитростями ещё тестировать долго в разных ситуациях надо, а нормализация уже работает. Берите и пользуйтесь!
 
olyakish писал (а):
ТК я умножением на 100000000 вывел все числа после запятой на Print и могу глазками сказать\утверждать о отсутсвии "мусора" в этих двух числах

По этому я считаю что это все же ошибка.

Дело не в мусоре, а в представлении чисел типа double в памяти.

 

Нормализация не помогла. Поэтому был сделан более сложный вариант (см. выше).


Еще один ответ на эту же тему от программиста, не работающего с МТ:


Я не знаю как в СИ, но в Паскиле, например, при сравнении двух значений типа float проблема может быть в следующем.
В памяти, в зависимости от точности выражения числа с плавающей точкой два числа могут быть сохраненые как
1.4000999567 и 1.4000994678
При округлении до нужной нам точности они равны, а так - нет.

Я делал деление на TickSize и сравнивал целую часть чисел (через Round, естественно). По другому, ИМХО, никак.

ЗЫ. Ещё одна "неприятность с МТ, Ами и тому подобным - невозможно сделать трассировку с анализом содержимого переменных.


 
KimIV:
Алексей, я чё-та не понимаю, Вам ехать или шашечки? Если ехать, то нормализуйте. И не надо никаких премудростей. Просто - надёжно! То, что Вы придумаете умножением и прочими хитростями ещё тестировать долго в разных ситуациях надо, а нормализация уже работает. Берите и пользуйтесь!
Дело в том что практически каждый наступал на эти "грабли"

постов на эту тему было огого... но я все же хотел из логических соображений прийти к правде а не обходить подобного рода ситуации.

Для меня изначально было достаточно знать что есть 15 символов после запятой и типа гдето тут должен быть подвох

если рассуждать логически дальше то либо там не 15 а почему то больше либо на моменте сравнения привязывается какой то мусор

Вообще чтобы в будующем все же таких пробем у других небыло то в терминале принудительно каждую переменую данного типа нормализовать до 15 символа

Как и "как" бы написано в документации.



А сейчас поедем как есть тоесть через....нормализацию или

а>b не всегда так а вот a-b>0 то это правильно ...

 
olyakish:

но я все же хотел из логических соображений прийти к правде а не обходить подобного рода ситуации.

Для меня изначально было достаточно знать что есть 15 символов после запятой и типа гдето тут должен быть подвох

Насколько я понимаю, значение переменной в отмеченных местах могут отличаться:

Причина обращения: