Вопрос к мастерам MQL4. Опять про Double Compare.

 
Здравствуйте!
Как известно, от стиля программирования и аккуратности в коде зависит не только правильность расчетов, но и надежность работы написанного кода.
Пишем не игрушки, а потому надежность работы написанной программы является самым первым требованием. Большинство расчетов производится в даблах и корректное сравнение в коде
программы двух вещественных чисел, требует определенного подхода и аккуратности.
Пытаюсь выработать "правильный" стиль программирования. Отсюда вопрос:

Для выражения

double a;
double b;

if(a==b) или if(a!=b)
{......} {......}

разработчики рекомендуют так
//+------------------------------------------------------------------+
//| Функция сранения двух вещественных чисел. |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
return(Compare);
}
//+------------------------------------------------------------------+


Корректен ли код?

double a;
double b;

if(a>b) if(a<b)
{......} {......}


Скорей всего, что в общем случае нет. Какой способ корректной проверки избрать?
Какой вообще стиль работы с даблами целесообразнее?
Заранее благодарен всем откликнувшимся.
 

я предпочитаю использовать для сравнения по возможности знаки больше и меньше,

double a;
double b;
 
if(a>b)             if(a<b)
    {......}            {......}

дабы особо не заморачиватся на проиведение double к определенной разрядности

Vol = 156.00000002; 
NormVol = NormalizeDouble(Vol,2); 
156.00

если вседаки необходимо именно ставнить числа

if(a==b)    или         if(a!=b)
    {......}                    {......}

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

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......}
 
xeon:

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

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
А при расчетах в индикаторах Вы используете Normalize и подобные подготовки?
Просматриваю много кода, учусь программировать и редко где в коде индикатора это встречается. Вот вопрос и возник - как по хорошему-то надо.
 
VBAG:
xeon:

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

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
А при расчетах в индикаторах Вы используете Normalize и подобные подготовки?
Просматриваю много кода, учусь программировать и редко где в коде индикатора это встречается. Вот вопрос и возник - как по хорошему-то надо.

независимо индикатор, скрипт или эксперт, нарватся на несоответствие double можно везде, поэтому я стараюсь этого избежать используя NormalizeDouble или используя знаки "<" и ">"
 
xeon ,
Спасибо за Ваше мнение.
 
Нормализуйте всегда, и проблем с даблами никогда не будет! ;)
При любом сравнении, любые даблы, и с осознанно выбранной точностью.

//--- NormalizeDouble
double nd( double value, int precision )
{
    return( NormalizeDouble( value, precision ) );
}
 
//--- MathAbs
double abs( double value )
{
    return( MathAbs( value ) );
}
 
//--- Если value1 равняется value2 до precision знака после запятой, возвращает true, иначе - false.
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( nd( value1, precision ) - nd( value2, precision ) ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}

Обратите внимание на функцию equal - если ее чуть изменить:
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( value1 - value2 ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}
(убрать нормализацию каждого числа перед сравнением), она будет давать другой результат.

Например, equal( 0.123456784, 0.123456776 ) в первом варианте вернет true, а во втором - false ;)
 
komposter:
Нормализуйте всегда, и проблем с даблами никогда не будет! ;)
Зато будут проблемы с производительностью. Проблема сравнения чисел с двойной точностью надумана и исходит от элементарного незнания матчасти.
 
Irtron:
Проблема сравнения чисел с двойной точностью надумана и исходит от элементарного незнания матчасти.

Поясню.

Очевидно, происходит смешивание понятий. Есть тип числа с плавающей точностью, который в intel архитектуре используется для представнения чисел с фиксированной точностью, к которым, в частности, относятся все величины торгового окружения, потому как в процессоре есть специальная молотилка для плавающей арифметики.

На самом деле, числа с фиксированной точностью очень мало отличаются от целых чисел с точки зрения машинного представления. Наличие десятичного знака в этом случае условно. Это свойство широко используется в архитектуре, в которой плавающая арифметика аппаратно не поддерживается, например, в ARMе, получившем распространение благодаря использованию в PDA и смартфонах. Плавающую арифметику там приходится эмулировать довольно тяжелым кодом, что здорово греет процессор и, соответственно, сажает батарею, не говоря уж о скорости выполнения программы. Поэтому везде, где нельзя обойтись целыми числами, используется фиксированный формат. Плавающая точность применяется в самых крайних случаях. Вернее, конечно, должна бы применяться.

Ничто не мешает использовать фиксированную (то бишь целочисленную) арифметику для рыночных величин.

Это не относится к расчетным значениям индикаторов. Там вполне достаточно прямого сравнения. Зачем их сравнивать с какой-то точностью?
 
Спасибо komposter и Irtron ! Уже решил, что больше ничего не напишут и сел придумывать сам и не видел ваши посты.
Посмотрите пожалуйста, что накропал своей корявой рукой:
//+------------------------------------------------------------------+
bool EqualDouble(double dN1, double dN2,int Digit)
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 == 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool LessDouble(double dN1, double dN2,int Digit) // Если dN1<dN2
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d2-d1 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool MoreDouble(double dN1, double dN2,int Digit) // Если dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
 
VBAG:
Посмотрите пожалуйста, что накропал своей корявой рукой:
Вы какие величины пытаетесь сравнивать? Цены, лоты или значения индикаторов?
 
Irtron:
VBAG:
Посмотрите пожалуйста, что накропал своей корявой рукой:
Вы какие величины пытаетесь сравнивать? Цены, лоты или значения индикаторов?
Я в начале писал: "Пытаюсь выработать "правильный" стиль программирования. "
А по сути, какая разница, что в даблах лежит-только точность округления Digit будет разная, в зависимости от требований к переменной.
Причина обращения: