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

 
SK. писал (а):

Esta conversación parece prolongarse indefinidamente. Cuando un nuevo usuario ha adquirido la experiencia y los conocimientos adecuados, suele tener tiempo de toparse con la normalización varias veces.

Tal vez en MT5 tenga sentido limitar forzosamente la precisión de los números reales al realizar operaciones de comparación, por ejemplo, a 8 decimales (es decir, ejecutar forzosamente NormalizeDouble() con digit=8).

No esperaría eso de ti. ¡No, en absoluto!
Si la operación de comparación se utilizará repetidamente (en cálculos recurrentes, etc.), entonces redondeando a 8 dígitos en la entrada, el error de salida puede ser proporcional a 1.

Tuve esa experiencia con el cálculo de SmoothedAvarege, calculándolo en mi aplicación hace un año. Después de eso, estoy tratando de elegir tales métodos de trabajo que no afectan a la capacidad de dígitos de los dobles.
O, como sugirió gravity001 , cambiar a INTam (que, como comprenderás, requiere mucho tiempo).
 
SK. писал (а):

Tal vez en MT5 tenga sentido limitar a la fuerza la precisión de los números reales cuando se realicen operaciones de comparación a, por ejemplo, 8 decimales (es decir, realizar forzosamente NormalizeDouble() con digit=8).


Sin embargo, no sólo las operaciones definidas por el usuario ralentizan el terminal, sino también las operaciones ocultas. Me parece preferible introducir simplemente la función ComparePrice en el lenguaje. Por cierto, al igual que Irtron, considero que Punto/2 es una medida natural (quizás mejor Punto *0,5). Para evitar dividir/multiplicar cada vez, esta mitad puede convertirse en una variable predefinida. Hasta que no exista, puedes introducir tú mismo dicha variable y calcularla una vez en el primer arranque. Aunque, los desarrolladores pueden hacer la función de doble comparación con precisión predefinida, es decir, lo mismo, pero con dígitos en lugar de Punto/2.
 
Depfy:

Has hecho un lío... :)

La comparación de números flotantes se realiza comparando el módulo de diferencia con un pequeño umbral.

Devuelve (fabs(d1-d2) < 1e-10) por ejemplo.

¿Qué sentido tiene enredar las aguas... La función NormalizeDouble(...) es sólo para obtener informes de aspecto agradable.

Gracias por el ejemplo.
Pero no lo entiendes, tienes que leer con más atención. La esencia de la cuestión es el estilo de programación en general, y en el caso concreto de MT4.
 
VBAG:
Depfy:

Has hecho un lío de las cosas... :)

La comparación de números flotantes se realiza comparando el módulo de diferencia con un pequeño umbral.

Devuelve (fabs(d1-d2) < 1e-10) por ejemplo.

¿Qué sentido tiene enredar las aguas... La función NormalizeDouble(...) es sólo para obtener informes de aspecto agradable.

Gracias por el ejemplo.
Pero no lo entiendes, tienes que leer con más atención. La esencia de la cuestión es el estilo de programación en general, y en el caso concreto de MT4.

Será mejor que nos diga cuál es el objetivo de esta pregunta. De lo contrario, las pistas - no entiendo :)

Si hablamos de velocidad, los procesadores modernos realizan operaciones en coma flotante

casi tan rápido como los enteros. En cuanto al ESTILO, lo siento, el pragmatismo manda...

Cuando se trata de ASHIPS, de qué tipo de estilo estamos hablando... Siempre y cuando funcione. ...

Por lo demás, no hay más problema que comparar dos números :))))))))

 
VBAG:
No esperaba algo así de ti. ¡No debes hacer eso en ningún caso!
Si la operación de comparación se va a utilizar repetidamente (en cálculos recurrentes, etc.), entonces si se redondea a 8 dígitos en la entrada, el error de salida puede ser proporcional a 1.

Tuve esa experiencia con el cálculo de SmoothedAvarege, calculándolo en mi aplicación hace un año. Después de eso, estoy tratando de elegir tales métodos de trabajo que no afectan a la capacidad de dígitos de los dobles.
O, como sugirió gravity001 , cambiar a INTam (que, como comprenderás, requiere mucho tiempo).


Espera un momento. No es necesario sacar conclusiones precipitadas.

En primer lugar. No propongo redondear a la fuerza el valor real de la propia variable real. Propongo forzar el redondeo de los valores comparados (copias) de las variables al calcular el resultado de una operación de comparación (para el caso por defecto). Y, por supuesto, no se debe tocar el valor real de la variable. En este caso, ningún otro valor calculado se vería afectado, porque los valores originales de las variables utilizadas en las operaciones de comparación conservan sus valores, y los errores en los cálculos cíclicos no se acumularían.

Segundo. He dicho que para eliminar los errores con consecuencias más duras, podemos ir por este camino. Sin embargo, para proporcionar también cálculos más exigentes, es necesario conservar la posibilidad de utilizar la funciónNormalizeDouble() con parámetros especificados.

Así que mi sugerencia no limita las capacidades del lenguaje, sino que las amplía.

Sin embargo, teniendo en cuenta que en las operaciones de comparación, por regla general, se utilizan valores de precio (es decir, dígito = 4), en la gran mayoría de los casos este error simplemente no se producirá. Así, el uso de la tecnología propuesta reducirá el número de errores que conducen a consecuencias imprevisibles.

 
lna01:
Y mientras esto no esté disponible, se puede introducir dicha variable y calcularla una vez en el primer inicio de arranque.

No se puede.

O mejor dicho, se pueden escribir cadenas de programa, pero nadie (incluidos los desarrolladores) garantizará que el valor de esta variable permanezca estrictamente inalterado durante toda la vida del EA. No se trata de la precisión del código del programa, sino de las características tecnológicas de los cálculos y de las reglas tecnológicas para almacenar los valores de las variables. Si no fuera así, este problema ni siquiera existiría.

En la actualidad, el valor inicial de la variable 123.00000000000 puede aparecer como 122.999999999999 en el momento en que se utiliza en los cálculos. Esto es así a pesar de que el valor de la variable no ha cambiado nunca desde su creación y sólo ha sido llamada por el programa para participar en otros cálculos.

De hecho, es por esto que hubo todo este alboroto. Por eso hemos creado la necesidad de utilizar NormalizeDouble() lo más cerca posible del cálculo real, preferiblemente directamente en la condición de las sentencias if, for, while.

 
SK. писал (а):
lna01:
Y mientras eso no esté disponible, puedes introducir tú mismo dicha variable y calcularla una vez en el primer inicio de la partida.

No se puede.

O mejor dicho, se pueden escribir cadenas de programa, pero nadie (incluidos los desarrolladores) garantizará que el valor de esta variable permanezca estrictamente inalterado durante toda la vida del EA. No se trata de la precisión del código del programa, sino de las características tecnológicas de los cálculos y de las reglas tecnológicas para almacenar los valores de las variables. Si no fuera así, este problema ni siquiera existiría.

En la actualidad, el valor inicial de la variable 123.00000000000 puede aparecer como 122.999999999999 en el momento en que se utiliza en los cálculos. Esto es así a pesar de que el valor de la variable no ha cambiado nunca desde su creación y sólo ha sido llamada por el programa para participar en otros cálculos.

De hecho, es por esto que hubo todo este alboroto. Por eso necesitaba utilizar NormalizeDouble() lo más cerca posible del cálculo real, preferiblemente justo en la condición de las sentencias if, for, while.

Caramba, creo que empiezo a entender por qué tanto alboroto...

En definitiva, creo que no hay que inventar nada. Todo depende de la situación. ¿Cuál es el objetivo? Si dos números pueden diferir en la mantisa 0,1, y si es CRÍTICO, es una cosa, si no es importante, es otra. Depende de lo que se compare entre sí. Pero la FLEXIBILIDAD, dada por un compilador REAL sin florituras, es algo REAL y necesario, IMHO.

:)

 
SK. писал (а):
La cuestión no es la exactitud del código del programa, sino las características tecnológicas de los cálculos y las reglas tecnológicas para almacenar los valores de las variables. Si no fuera por eso, no se habría planteado la cuestión.
Es cierto lo de los cálculos, pero me pareció que todo debe ser mejor con el almacenamiento. Y cuando los dígitos = 4, la diferencia en el 15º dígito no debería influir.
 
Depfy:

Caramba, creo que empiezo a ver por qué tanto alboroto...

En general, no creo que haya nada que inventar. Porque todo depende de la situación concreta. ¿Cuál es el objetivo? Si dos números pueden diferir en la mantisa 0,1, y si es CRÍTICO, es una cosa, si no es importante, es otra. Depende de lo que se compare entre sí. Pero la FLEXIBILIDAD, dada por un compilador REAL sin florituras, es algo REAL y necesario, IMHO.

:)


No puedo responder a lo de "inventarse". Aparentemente, depende de lo que se piense:)

Por ejemplo, en algunos casos invenciones como Point/2 permiten realmente hacer cálculos con cierta precisión. Sin embargo, es mejor utilizar la recomendación de los desarrolladores, es decir, de una vez por todas (hasta la nueva documentación) tomar como regla el uso de la función NormalizeDouble() al calcular operaciones de comparación.

 
lna01:
SK. escribió (a):
La cuestión no es la exactitud del código del programa, sino las características tecnológicas de los cálculos y las reglas tecnológicas para almacenar los valores de las variables. Si no fuera por eso, la pregunta ni siquiera se habría planteado.
Eso es cierto para los cálculos, pero pensé que debería ser mejor para el almacenamiento. Y con dígitos = 4, la diferencia en el 15º dígito no debería importar.

Y no importará si usas NormalizeDouble(). Y si no lo usas, es cuestión de suerte.
Razón de la queja: