Операция "меньше" некорректно обрабатывается

 
Здравствуйте.
Столкнулся с ошибкой OrderModify error 1
код такой

if(price<OrderOpenPrice())OrderModify(....

Сделал вывод переменных:

if(price<OrderOpenPrice())Print(price+" "+OrderOpenPrice());

Выводится одинаковая цена, например "1.61853 1.61853".

Переписал условие на:

if(price<=OrderOpenPrice()-1*Point)

Работает нормально.
Но почему первый вариант некорректно работал?
 

уточню, что ордер BuyStop и в переменной price высчитывается цена, на которую надо переместить отложенник.

Так же проверяется если price близко к цене Ask, то к price прибавляется STOPLEVEL

 
alexejshevchenk:

уточню, что ордер BuyStop и в переменной price высчитывается цена, на которую надо переместить отложенник.

Так же проверяется если price близко к цене Ask, то к price прибавляется STOPLEVEL

А что означает ошибка 1 вы в курсе? Не пытайтесь изменить 10 на 10
 

Поищите как правильно сравнивать числа типа double

 
artmedia70:
А что означает ошибка 1 вы в курсе? Не пытайтесь изменить 10 на 10

Я знаю что означает ошибка 1, но вопрос не в этом, а почему данное условие сработало. Ведь новая цена НЕ меньше предыдущей.


ALXIMIKS, Спасибо большое. Нашёл статью и разобрался. Это особенность mql4

 


ALXIMIKS, Спасибо большое. Нашёл статью и разобрался. Это особенность mql4


Нет, это особенность представления чисел с плавающей точкой в компьютере: все, что не может быть представлено точным двоичным числом будет давать такой эффект. В некоторых языках от программистов это просто скрыто - то есть компилятор/интерпретатор "сам разбирается".
 
VladislavVG:

Нет, это особенность представления чисел с плавающей точкой в компьютере: все, что не может быть представлено точным двоичным числом будет давать такой эффект. В внонекоторых языках от программистов это просто скрыто - то есть компилятор/интерпретатор "сам разбирается".

Я Вас правильно понял? Если бы число было меньше, например 0.3, то оно было бы представлено как двоичное число с фиксированной запятой и сравнение проходило бы правильно?

А почему 2 одинаковых дроби представляются как разные числа с плавающей точкой?

Я взял price равное фракталу. Котировки с точностью до 5 знака. т.е. цена имеет вид 1,12345. И сравниваю с ценой Ask, которая тоже имеет точность 5 знаков. Они найдены 2-мя разными путями, но они же округлены?!

т.е. нам надо сравнить 2 числа 1,12345 и 1,12345. Если их перевести в двоичное число с плавающей точкой, то получится одно и тоже число. Почему тогда получается такой результат?


Исправил на:

NormalizeDouble(price,Digits)<NormalizeDouble(OrderOpenPrice(),Digits)

теперь нормально работает условие. Видимо при сравнении число округлялось до 4 знаков после запятой

 
alexejshevchenk:

Я Вас правильно понял? Если бы число было меньше, например 0.3, то оно было бы представлено как двоичное число с фиксированной запятой и сравнение проходило бы правильно?

А почему 2 одинаковых дроби представляются как разные числа с плавающей точкой?

Я взял price равное фракталу. Котировки с точностью до 5 знака. т.е. цена имеет вид 1,12345. И сравниваю с ценой Ask, которая тоже имеет точность 5 знаков. Они найдены 2-мя разными путями, но они же округлены?!

т.е. нам надо сравнить 2 числа 1,12345 и 1,12345. Если их перевести в двоичное число с плавающей точкой, то получится одно и тоже число. Почему тогда получается такой результат?


Исправил на:

NormalizeDouble(price,Digits)<NormalizeDouble(OrderOpenPrice(),Digits)

теперь нормально работает условие. Видимо при сравнении число округлялось до 4 знаков после запятой

Скажите, у Вас информатика в школе была ? Не могу же я Вам весь курс здесь пересказывать.
 
VladislavVG:
Скажите, у Вас информатика в школе была ? Не могу же я Вам весь курс здесь пересказывать.


Ну, во первых, в школьной программе не так глубоко изучают информатику! И в вышке не так углублялись, т.к. это был не мой профиль.


Сами сказали: "В некоторых языках от программистов это просто скрыто - то есть компилятор/интерпретатор "сам разбирается"."

Почему же если в C# написать

double a = 1.123456789;

double b = 1.123456789;

if(a<b) Console.WriteLine("a<b");

else if (a > b) Console.WriteLine("a>b");

else if (a == b) Console.WriteLine("a=b");

Console.ReadLine();


то он выдаст "="?

"все, что не может быть представлено точным двоичным числом будет давать такой эффект." это Ваши слова. Или число 1,123456789 можно представить точным двоичным числом?


Если в других языках такие сравнения проходя нормально, а в mql4 нет, то, мне кажется, это не от моего незнания информатики.

 
alexejshevchenk:

Ну, во первых, в школьной программе не так глубоко изучают информатику! И в вышке не так углублялись, т.к. это был не мой профиль.


Сами сказали: "В некоторых языках от программистов это просто скрыто - то есть компилятор/интерпретатор "сам разбирается"."

Почему же если в C# написать

double a = 1.123456789;

double b = 1.123456789;

if(a<b) Console.WriteLine("a<b");

else if (a > b) Console.WriteLine("a>b");

else if (a == b) Console.WriteLine("a=b");

Console.ReadLine();


то он выдаст "="?

"все, что не может быть представлено точным двоичным числом будет давать такой эффект." это Ваши слова. Или число 1,123456789 можно представить точным двоичным числом?


Если в других языках такие сравнения проходя нормально, а в mql4 нет, то, мне кажется, это не от моего незнания информатики.



Этот код сработает и в mql4, а источник ошибки: "...в переменной price высчитывается цена ...".

Одно дело указать Константа==Константа, другое - ВычисляемоеЗначение==Константа.

ЗЫ Попробуйте на примере 4/3=1.333

 
tara:


Этот код сработает и в mql4, а источник ошибки: "...в переменной price высчитывается цена ...".

Одно дело указать Константа==Константа, другое - ВычисляемоеЗначение==Константа.


Опередили. )))))

2 alexejshevchenk тогда попробую проще: в числе с плавающей точкой всегда хранится 15 знаков после запятой, даже если Вы видите только 4 или 5. Разница может быть в невидимой Вами части. Потому самый правильный способ сравнения цен - это сравнение их разности с размером пункта ( или 0.5*Point). Тогда и округлять не обязательно. При вводе констант, естественно, всегда получите равенство, при расчетах - нет.

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