Errores, fallos, preguntas - página 2821

 
Igor Makanu:

la normalización no es un redondeo

Tengo un sobresaliente en teoría, en cómo trabajar con el doble y demás. El algoritmo NormalizeDouble contiene un error. El tema planteado sólo está relacionado indirectamente con la comparación de dobles.

 
fxsaber:

Repito mi pregunta.

La imagen muestra el valor de la variable no normalizada n y el de la variable normalizada m y lo diferentes que son. Pero si quieres comparar tangas, es tu preferencia.

fxsaber:

Conozco la teoría, cómo trabajar con el doble y cosas así en una escala A+. El algoritmo NormalizeDouble contiene un error. El tema planteado sólo está relacionado indirectamente con la comparación de dobles.

Definitivamente no puede prescindir de la explicación de Semko aquí.
 
NormalizeDouble es sólo un cierto algoritmo que se aplica a un número doble. Lamentablemente, hay un error en él. Si se corrige, el error desaparecerá. La doble representación de todos los demás no cambiará en absoluto.
 
fxsaber:

El algoritmo NormalizeDouble contiene un error.

Creo que A100 escribió sobre ello

pero los desarrolladores desde MQL se han ceñido a esta "característica", por desgracia


fxsaber:
Si lo corrigen, el error desaparecerá.
Creo que aparecerán otros fallos y habrá mucho ruido ))))
 
Igor Makanu:

Creo que aparecerán otros fallos y habrá mucho ruido ))))

No lo harán, porque casi todo el mundo compara incluso los doblajes normalizados a través de la normalización. Es decir, lo ponen donde quieren.


Una normalización adecuada debería dar siempre resultado en esta condición.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Errores, fallos, preguntas

fxsaber, 2020.08.10 11:37

  Print((double)(string)Norm == Norm);    // false

Esta es la única comprobación de que la normalización es correcta. Si siempre dará la razón, nada se romperá.

 
fxsaber:
NormalizeDouble es sólo un cierto algoritmo que se aplica a un número doble. Lamentablemente, hay un error en él. Si se corrige, el error desaparecerá. Todas las demás representaciones dobles no cambiarán por ello.
Creo que no se trata de la función, sino de que las constantes no están normalizadas por el compilador (aunque deberían estarlo).
Lo mismo ocurre con la conversión de cadena a doble.
 
Alexey Navoykov:
Creo que no se trata de la función, sino de que las constantes no están normalizadas por el compilador (aunque deberían estarlo).
Lo mismo ocurre con la conversión de cadena a doble.

Entonces las mismas constantes en DLL y MQL no coincidirán.

 
fxsaber:

Entonces las mismas constantes en DLL y MQL no coincidirán.

También es cierto. Además, cualquier normalización supone una pérdida de precisión, así que puede que me haya pasado con la normalización de las constantes.
En general, este problema, en mi opinión, no tiene una solución inequívoca, aunque en realidad no lo es.
 
Alexey Navoykov:
También es cierto. Además, cualquier normalización supone una pérdida de precisión, así que puede que me esté pasando con la normalización constante.
En general, este problema no me parece que tenga una solución inequívoca, aunque en esencia no lo sea.

Sólo hay que modificar el algoritmo de normalización actual.

 
fxsaber:

Sólo hay que modificar el algoritmo de normalización actual.

void OnStart() {
   double d1=1.79435;
   double d2=NormalizeDouble(1.79435,5);
   Print(d1==d2);
   Print(is_equal(d1,d2,_Point/2));
}
//+------------------------------------------------------------------+
bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}

Ni siquiera sé si se trata de un error en el algoritmo.
Realmente, no se pueden comparar los dobles. Sólo una regla dura.
O, como dice Slava, a través de épsilon o a través de la multiplicación (por ejemplo, por 1/_Punto) con conversión a int con redondeo.

Sólo el redondeo no se realiza con round(), ceil(), floor() ya que también devuelven double.

O a través de estos, sobre todo porque funcionan más rápido que los normales:

int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;}
int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;}

Más fácil y rápido, por supuesto, a través de epsilon:

bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}
Razón de la queja: