Pregunta a los maestros del MQL4. De nuevo sobre la doble comparación. - página 5

 

¡Increíble conclusión! ¿Qué te hace pensar que con cualquier dígito, si ni siquiera "entiendes" lo que es un dígito en absoluto?

 
Integer:

¡Increíble conclusión! ¿Qué te hace pensar que con cualquier dígito, si ni siquiera "entiendes" lo que es un dígito en absoluto?

¿Empiezas a meterte con las palabras? Obviamente, esto va a ser un asesinato de personalidad. :)
Debo decir de inmediato que prefiero no participar en esas explicaciones, porque si no tienes nada que decir sobre el fondo, ¿para qué hablar?
 
VBAG:
Me gustaría dar las gracias a todos los profesionales por sus conocimientos.

Irtron, he elegido tu variante, me ha gustado mucho. Lo he corregido un poco para casos generales y lo he comprobado:

int CompararPrecio(double a, double b, double digit)
{
a -= b;
b = dígito;
si (a > b)
volver (1);
si (a < -b)
devolver (-1);
retorno (0);
}
Gracias.
Se me olvidó aclarar que quiero pasar cualquier valor predefinido a digit:
double digit14=0.00000000000001;
doble dígito12=0,000000000001;
doble dígito8=0,00000001;
doble dígito4=0,0001;
doble dígito2=0,01;
que determinará la precisión requerida.
Para esta funcionalidad, funciona muy rápidamente.
Irtron, gracias de nuevo.

 
Irtron:
Entero:

¡Increíble conclusión! ¿Qué te hace pensar que con cualquier dígito, si ni siquiera "entiendes" lo que es el dígito en absoluto?

¿Empezando a elegir palabras? Obviamente, se va a poner personal de aquí en adelante. :)
Debo decir de inmediato que prefiero no participar en esas explicaciones, porque si no tienes nada que decir sobre el fondo, ¿para qué hablar?


Para qué meterse, acabo de leer lo que has escrito. Es evidente que tu comprensión se ve obstaculizada por "tu flagrante... (diga usted la palabra)"

VBAG, ¿por qué reinventar la rueda cuando hay una función NormalizeDouble() que compara dos números más rápido que ComparePrice()?

 
Integer:

VBAG, ¿por qué reinventar la rueda cuando hay una función NormalizeDouble() que compara dos números más rápido que ComparePrice()?

La función compara dos números dobles y da la respuesta <, > o = con 14 decimales (NormalizeDouble() está limitada a 8 dígitos)
Si puedes sugerir una moto similar o mejores soluciones alternativas, estaré encantado de utilizarlas.
Respetuosamente,
Vladimir
 
VBAG:
Entero:

VBAG, ¿por qué reinventar la rueda cuando hay una función NormalizeDouble() que compara dos números más rápido que ComparePrice()?

La función compara dos números dobles y da la respuesta <, > o = con 14 decimales (NormalizeDouble() está limitada a 8 dígitos)
Si puedes sugerir una rueda similar o mejores alternativas, estaré encantado de utilizarlas.
Respetuosamente,
Vladimir
Aquí hay una prueba para mi interés:
int start()
  {
//----
    double a = 1.23450001, b = 1.23449999;
 
    int start1 = GetTickCount(), c1;
    for ( c1 = 0; c1 < 100000000; c1 ++ ) CD( a, b,0.00000001);
    int end1 = GetTickCount();
    
 
    int start2 = GetTickCount(), c2;
    for ( c2 = 0; c2 < 100000000; c2 ++ )   xNormalize(a,b,8);
    int end2 = GetTickCount();
 
    Print( "CD: ", (end1-start1), ", xNormalize: ", (end2-start2) );
 
    return(0);
   }
 
//+ CompareDouble ---------------------------------------------------+ CompareDouble
int CD(double a, double b, double digit)
{
    a -= b;
    b = digit;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
// Две операции NormalizeDouble----
bool xNormalize(double a, double b,int digit)
  {
   double d1 = NormalizeDouble(a,digit);
   double d2 = NormalizeDouble(b,digit);
   
//   bool bCompare=d2-d1 > 0.0;
   bool bCompare= 0;
   return(bCompare);
2007.09.12 07:15:09 $CheckCompareDouble USDJPY,M5: CD: 20485, xNormalize: 51265

Conclusión:
La función CD compara dos números dobles , da la respuesta <, > o = con 14 decimales y trabaja 2 veces más rápido que simplemente realizando NormalizeDouble()(incluso sin la lógica para compararlos).
 
Sí, dos llamadas a NormalizeDouble() tardan más que CD, y una llamada es más rápida. La precisión de 14 dígitos es un buen detalle :-)
 
Yo también he intentado comparar números reales últimamente.

Muchas personas escriben que para comparar deben utilizar la función incorporada NormalizeDouble(). (esto es lo que recomiendan también los desarrolladores).
Por lo tanto, primero me gustaría definir: "¿Qué es NormalizeDouble()?", es decir, cómo funciona, cuál es su algoritmo.

MQL4 Reference - Conversiones de datos - NormalizeDouble

Redondear un número de punto flotante a una precisión especificada.
...

No sé cómo se organiza el redondeo en MQL4 (pregunte a los desarrolladores), pero conozco un método estándar Redondear números de punto flotante a la precisión especificada:
Aquí, una función:

double MyNormalizeDouble(double value, int digits)
{
    int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                      с помощью которого мы из VALUE сделаем целое число
    double result = MathRound(factor * value) / factor;
    
    return(result);
}
En esta función se puede ver que primero pasamos de un número real a un número entero, y luego volvemos a un número real.
Para comparar, basta con pasar a un número entero.

Por lo tanto, creo que la forma más rápida y fiable de comparar números reales es convertirlos en enteros.
Así será la comparación:

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

Todo esto puede formarse en una función y utilizarse. ¡Es un dolor de escribir, parece que está claro cómo hacer una función!
Creo que esta forma es más rápida que llamar a NormalizeDouble().

Para estar seguro, también puedes hacer que la función MathRound() devuelva un entero, ya que por defecto devuelve doble.
La forma más fácil de hacerlo es de esta manera

int MyMathRound(double value)
{
    int result = MathRound(value);
    return(result);
}
Entonces sólo se compararán números enteros, ¡y se comparan bien!


Creo que esta forma es la más correcta, ¿no?
 
gravity001:

Así que creo que la forma más rápida y fiable es convertir los números reales en enteros
La comparación sería así:

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

Creo que es la forma correcta de hacerlo, ¿no?

No lo creo. Juzgue usted mismo:
Toda la belleza del código de Irtron radica en su compacidad (no hay absolutamente nada extra - ¡incluso las variables se guardan!).
Y sugieres que deberíamos añadir dos operaciones más por cada operación de
(а - b)
como mínimo.
(MathRound( (а - b) * factor ) 
¡Eso es una ventaja de velocidad!
 
VBAG:
No lo creo. Juzgue usted mismo

Sí, un poco más lento:
int start()
{
    double a, b;
    int start1, start2, end, c;
    
    a = 1.23450001;
    b = 1.23449999;
    
    start1 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        ComparePrice(a, b,0.0001);
    
    start2 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        intCompare(a, b,10000);
    
    end = GetTickCount();
 
    Print("ComparePrice: ", start2 - start1, ", intCompare: ", end - start2);
 
    return(0);
}
 
int ComparePrice(double a, double b, double point)
{
    a -= b;
    b = point / 2.;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
int intCompare(double a, double b, int factor)
{
    return(MathRound( (a-b) * factor ));
}
CompararPrecio: 32032, intCompare: 35296
Razón de la queja: