Pregunta a los maestros del MQL4. De nuevo sobre la doble comparación.

 
¡Hola!
Como sabes, no sólo la corrección de los cálculos, sino también la fiabilidad del código escrito depende del estilo de programación y de la pulcritud del código.
No escribimos juguetes, por lo que la fiabilidad del programa escrito es el primer requisito. La mayoría de los cálculos se realizan en dubles y una correcta comparación en el código de
de dos números reales en el código del programa requiere un cierto enfoque y precisión.
Estoy tratando de averiguar el estilo de programación "correcto", de ahí la pregunta:

Para una expresión

doble a;
doble b;

if(a==b) o if(a!=b)
{......} {......}

Los desarrolladores recomiendan esto
//+------------------------------------------------------------------+
//| Función de comparación de dos números reales. ||
//+------------------------------------------------------------------+
bool CompareDouble(double Número1, double Número2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
return(Compare);
}
//+------------------------------------------------------------------+


¿Es correcto este código?

doble a;
doble b;

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


Lo más probable es que no en el caso general. ¿Cuál es la forma correcta de comprobarlo?
En general, ¿qué estilo de trabajo con los doblajes es más apropiado?
Gracias de antemano a todos los que respondan.
 

Siempre que sea posible, prefiero utilizar los dígitos mayores y menores para comparar,

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

para no tener que preocuparme demasiado de que el doble llegue a un determinado dígito

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

Si es necesario juntar los números

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

entonces primero convierto ambos números en un solo dígito después del punto

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

Primero convierto ambos números en el mismo dígito después del punto

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
¿Y cuando se calcula en indicadores se utiliza Normalizar y preparaciones similares?
Estoy revisando mucho código, estoy aprendiendo a programar y rara vez se encuentra en el código del indicador. Esa es la cuestión: cómo hacerlo correctamente.
 
VBAG:
xeon:

Primero convierto ambos números en el mismo dígito después del punto

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
¿Utiliza Normalize y preparaciones similares en sus cálculos de indicadores?
Estoy revisando mucho código, estoy aprendiendo a programar y rara vez se encuentra en el código del indicador. Esa es la cuestión: cómo hacerlo correctamente.

Trato de evitarlo usandoNormalizeDouble o los signos "<" y ">", porque el indicador, script o Asesor Experto puede tener discrepancias en el doble.
 
xeon ,
Gracias por su opinión.
 
¡Normaliza siempre y nunca habrá problemas con los doblajes! ;)
En cualquier comparación, en cualquier chapuza, y con una precisión deliberadamente elegida.

//--- 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 ) );
}

Preste atención a la función de igualdad - si se cambia ligeramente:
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( value1 - value2 ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}
(eliminar la normalización de cada número antes de la comparación), dará un resultado diferente.

Por ejemplo, equal( 0.123456784, 0.123456776 ) devolverá true en el primer caso, pero false en el segundo ;)
 
komposter:
¡Normaliza siempre y nunca habrá problemas con los doblajes! ;)
Pero habrá problemas de rendimiento. El problema de la comparación de números con doble precisión es exagerado y proviene de la ignorancia básica de las matemáticas.
 
Irtron:
El problema de la comparación de números con doble precisión es exagerado y proviene de la ignorancia básica de las matemáticas.

Déjeme explicarle.

Obviamente, hay una confusión de nociones. Hay un tipo de número de punto flotante que se utiliza en la arquitectura de intel para representar números de precisión fija, que, en particular, incluyen todos los valores del entorno comercial, ya que el procesador tiene un trillador especial para la aritmética de punto flotante.

De hecho, los números de precisión fija se diferencian muy poco de los enteros en cuanto a su representación en la máquina. La presencia de un decimal en este caso es condicional. Esta propiedad se utiliza ampliamente en arquitecturas en las que la aritmética de punto flotante no está soportada por el hardware, como ARM, que se ha extendido por su uso en PDAs y smartphones. La aritmética flotante tiene que emularse con un código bastante pesado, que calienta el procesador y, por tanto, gasta la batería, por no hablar de la velocidad de ejecución del programa. Así, siempre que no sea posible hacerlo con enteros, se utiliza un formato fijo. La precisión flotante se utiliza en los casos más extremos. O más bien, por supuesto, debería serlo.

Nada impide el uso de la aritmética fija (es decir, entera) para los valores de mercado.

Esto no se aplica a los valores calculados de los indicadores. Una comparación directa es suficiente en este caso. ¿Por qué compararlos con precisión?
 
Gracias a komposter y a Irtron. Ya he decidido que no se va a escribir nada más y me he sentado a inventar y no he visto tus posts.
Por favor, mira lo que escribí con mi propia mano astuta:
//+------------------------------------------------------------------+
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) // Si 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) // Si dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
 
VBAG:
Por favor, vea lo que he garabateado con mi mano descuidada:
¿Qué valores está tratando de comparar? ¿Precios, lotes o valores indicadores?
 
Irtron:
VBAG:
Por favor, eche un vistazo a lo que he garabateado con mi mano descuidada:
¿Qué valores está tratando de comparar? ¿Precios, lotes o valores indicadores?
Escribí al principio: "Tratando de conseguir el estilo de programación 'correcto'. "
En esencia, no hay diferencia en lo que hay en los dubles - sólo la precisión del redondeo de Dígitos variará, dependiendo de los requisitos de la variable.
Razón de la queja: