Особенности языка mql5, тонкости и приёмы работы - страница 299

 
Putnik #:
Похоже авто переводчик глючит

Нет, все в порядке - 

 

ОК, спасибо.

С другого компа зашел, только одна ошибка.


 
Putnik #:

Лучше заменить a==b на (a-b)==0, так будет лучше.

Почему? Это операционно дороже, чем прямое сравнение.

Пожалуйста, объясните.
 
Dominik Egert #:
Почему? Это операционно дороже, чем прямое сравнение.

Пожалуйста, объясните.

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

А по сути изначальный вариант если и отличается, то совсем незначительно.

 
Dominik Egert #:
Почему? Это операционно дороже, чем прямое сравнение.

Пожалуйста, объясните.

Исходя из того, что операционно это будет дешевле. Так сказал учитель по информатике в школе. 

Сам я точно не могу сказать, спорить небуду.

 
Putnik #:
Так сказал учитель по информатике в школе

увольнять..

во первых это не быстрее, во вторых не очевиднее для читающего, наконец это дело компилятора такие микро-оптимизации. 

ну и под завязку не для всех доменов и классов разрешена (имеет смысл) операция "вычитание". Заменив оператор == на a-b==0 можно сделать программу невалидной

 
Alexey Viktorov #:

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

А на самом деле исходный вариант если и отличается, то очень незначительно.

Пожалуйста, без дискуссий. Но я, конечно, не согласен с этим утверждением.

a-b==0 так же точно, как a==b. Это справедливо для всех типов данных, в том числе и для парных. Иначе процессор перестал бы быть детерминированным.

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

То, чего вы добиваетесь, используя a-b==0, - это нечеткость вокруг очень большого значения при вычитании очень маленького значения, вы начинаете "привязывать" свой результат к верхней или нижней границе представления.

Это глючный код. Это нехорошо, и отлаживать его будет очень сложно.
 
Dominik Egert #:
Пожалуйста, без дискуссий. Но я, конечно, не согласен с этим утверждением.

a-b==0 так же точно, как a==b. Это справедливо для всех типов данных, в том числе и для парных. Иначе процессор перестал бы быть детерминированным.

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

То, чего вы добиваетесь, используя a-b==0, - это нечеткость вокруг очень большого значения при вычитании очень маленького значения, вы начинаете "привязывать" свой результат к верхней или нижней границе представления.

Это глючный код. Это нехорошо, и отлаживать его будет очень сложно.

Сравнение

if(iOpen(NULL, 0, 0) == iClose(NULL, 0, 0)) // не всегда работает
if(iOpen(NULL, 0, 0) - iClose(NULL, 0, 0) == 0) // всегда работает

Не знаю что быстрее, но нам также нужна надёжность условий

 
Dominik Egert # a-b==0 так же точно, как a==b. Это справедливо для всех типов данных, в том числе и для удвоенных.
double a = 0.1 + 0.2;
double b = 0.3;

Print("a = ", a);
Print("b = ", b);

a = 0.30000000000000004

b = 0.3

Именно поэтому a - b == 0 небезопасно для двоек.

Почему a != b? Потому что ни 0,1, ни 0,2, ни 0,3 не могут быть точно представлены в двоичном виде с типом double (64-битный IEEE 754).

 
Vitaly Muzichenko #:

Сравнение

Не знаю что быстрее, но нам также нужна надёжность условий

В данном конкретном примере ещё надёжнее так:

if(MathAbs(iOpen(NULL, 0, 0) - iClose(NULL, 0, 0)) <_Point)

Да собственно и во всех остальных с double числами.