Implementaciones alternativas de funciones/enfoques estándar - página 9

 
fxsaber:

Llegó al punto en que el problema ya no se produce y se olvidó con seguridad de él. Es estupendo no tener que volver a un código ya escrito. Funciona, eso es lo principal.

Así es. Siempre lo hago yo (y esta vez también, como puedes ver).

El problema surgirá si algo cambia de repente. Cuando el código es claro y los lugares no obvios están bien comentados, las causas de los errores en algunos cambios son fáciles de encontrar. Pero en estos casos de "y olvido" - es mucho más difícil hacer correcciones.

Sí, claro, que es un caso raro... Pero estos casos muy raros - personalmente estoy muy nervioso. Por eso, en estas situaciones, intento escribir un código claro en la medida de lo posible y dar comentarios detallados en los lugares no obvios.

 
fxsaber:

Un ejemplo de mi código, que ahora mismo no entiendo nada. Y hay muchos factores que hay que entender muy bien.


Como puedes ver, el código/estilo es muy sencillo. Pero sólo podré detectar un error en él o su ausencia cuando pueda volver a escribir el mismo código. Realmente me va a llevar mucho tiempo, ya que necesito entrar en el problema por completo.

Por eso el principio es que las cosas complejas se limpian (se escriben las pruebas de esfuerzo) en la etapa de creación y se utilizan de forma simple al enchufar mqh. Como puede ver, la complejidad no siempre viene determinada por el estilo o la brevedad.


También hay un ejemplo de construcciones puramente lingüísticas: TypeToBytes. La complejidad de la comprensión es un nivel muy diferente. Y aquí es donde me marchitaría sin las macros. Gracias a las macros, se entra en el código fuente con bastante rapidez. Porque las macros se utilizan a menudo no para la brevedad, sino para la comprensión.


Y también está el caso en el que hay que tener en cuenta un montón de escollos poco complicados pero olvidables. Este es el caso de MT4Orders. Por eso algunas líneas van acompañadas de comentarios dirigidos sólo a uno mismo. Ayuda a entender su código.


Pero ten en cuenta que todos estos son mqh, en los que no necesitas entrar. Y el código de TC está escrito con mqh, que es muy sencillo. No se mira el código fuente de las funciones regulares de iHigh. Y son monstruosos, en efecto. Sólo tienes que usarlos. Debería hacer lo mismo con las bibliotecas. El mismo genérico-biblioteca para usar no requiere que lo entiendas completamente.


Mira el QB para los EAs de MT4 y sus puertos de MT5. Los puertos de MT5 son un cojo para entender. No sólo no huele a concisión (el código es muchas veces más grande que el original), sino que también tiene trampas de MT5 que no se tienen en cuenta en los archivos mqh.

Sinceramente, no tengo nada que discutir aquí. Evidentemente, todo es correcto según tu enfoque de la programación (quizá sólo con la excepción de los casos de compresión excesiva e injustificada del código), pero si adoptas mi enfoque, muchas cosas están mal.

1. Por supuesto, los errores difíciles de encontrar pueden esconderse incluso en un código muy sencillo. Pero son aún más difíciles de encontrar en un código difícil de escribir. Piensa en el esfuerzo mental que supone desentrañar el significado. Si tienes que hacer una gran cantidad de trabajo (escribir muchas funciones, construir nuevos mecanismos, integrarlos con éxito en los existentes), ahorrar tiempo y esfuerzo es lo principal. No se trata de la "belleza" del código. No se trata de estilos. Tienes que componer tu código de tal manera que puedas leerlo en mitad de la noche y entenderlo lo más rápidamente posible. Empiezas a buscar el método ideal de codificación para obtener el máximo resultado de ti mismo. Y mirándolo:

return((int)((Value > 0) ? Value / Points[digits] + HALF_PLUS : Value / Points[digits] - HALF_PLUS) * Points[digits]);

inmediatamente comprenderá todas las desventajas de escribirlo de esta manera:

1. Un montón de personajes.

2. Excesivo "empaquetamiento".

3. operaciones matemáticas no comentadas.

No podrás manejar este código mientras estés despierto. También es difícil hacer frente a la sobrecarga de trabajo y al cansancio. Imagina que trabajas así todos los días. Se aleja inmediatamente de tal código.


2. ¿No mira el código de otras personas y se limita a enchufarlo?

Creo que los programas grandes, serios y, lo que es más importante, de alta calidad, no se crean simplemente ensamblando los bloques de otras personas. No se puede crear un programa eficiente creando sólo una pequeña parte y adjuntando el resto. Será un "lío".

Puede funcionar y funcionará. Pero se trata de programas "improvisados".

No creo en la eficacia de los programas montados a partir de bloques (en los que el desarrollador ni siquiera se fija). Esto es una ficción. El programa estará cojo y las soluciones serán ineficaces. Habrá muchos problemas. Si los programadores trabajan en equipo y resuelven una tarea común, es bueno, pero si se utilizan soluciones que "flotan" entre distintos programas de diferentes personas (que ni siquiera las miran), no es nada desde el punto de vista de la eficiencia.

 
Реter Konow:

Puede funcionar y funcionará. Pero esto es, - programas "de rodillas".

Puede consultar mis publicaciones en KB. Alguien debe estar usándolos.

Escribo sólo para mí y "de rodillas". Las publicaciones son un subproducto.

 
Georgiy Merts:

Así que la comprobación de LONG_MAX - debería ser antes de convertir double en long. Claramente, la función de redondeo no está diseñada para valores que no caben en un entero. Y eso no cambia el problema.

Si la función devuelve double, que luego convertimos en long, nos enfrentamos al mismo peligro de desbordamiento.

Personalmente, siempre tengo la comprobación de los valores límite justo antes del redondeo; además, la lógica del programa es que siempre me aseguro de que un valor mayor que el máximo para un entero nunca puede llegar a la transformación.

¿Sueles hacer lanzamientos largos hacia el carbón? Es lo mismo que con double - es el último peldaño de la jerarquía, no es necesario fundirlo, en la mayoría de los casos no es necesario, std tiene todo para trabajar con él. No deseches la jerarquía y no te preocupes.

Añade comprobaciones en LONG_MAX/MIN - y algo me dice que las pruebas de rendimiento no serán tan halagüeñas. Y la persona está apuntando a la sustitución std, por lo que debería funcionar para todo el rango de valores.

 
pavlick_:

¿Lanzas largo en char a menudo? Lo mismo ocurre con dabl - es el último peldaño de la jerarquía, no hay necesidad de lanzar desde él, en la mayoría de los casos no hay nada que hacer con él, std tiene todo para trabajar con él. No eches abajo la jerarquía y no te molestes.

Añade comprobaciones para LONG_MAX/MIN y seguro que las pruebas de rendimiento no tendrán tanta suerte. Y el hombre está apuntando a la sustitución std, por lo que debería funcionar para toda la gama de valores.

largo a ultralargo (y viceversa) - con demasiada frecuencia.

largo para char - rara vez.

La conversión es necesaria porque las operaciones con enteros y con coma flotante tienen resultados muy diferentes. La velocidad de ejecución de los datos enteros también es supuestamente más rápida.

Sobre la comprobación del rango - ya he subrayado que es ASSERT - es decir, tal comprobación funciona sólo en la versión DEBUG. En mi caso, todos los parámetros de entrada se comprueban siempre para el rango válido con aserciones al principio de cualquier función pública, lo que me ayudó más de una vez. Las versiones RELEASE, por supuesto, ya funcionan sin ninguna comprobación.

 
fxsaber:

Puedes echar un vistazo a mis publicaciones en KB. Alguien debe estar usándolos.

Escribo sólo para mí y "de rodillas". Las publicaciones son un subproducto.

No estoy cuestionando su experiencia y profesionalidad.

Es sólo que en el proceso de programación y desarrollo agotador y diario durante varios años empiezas a estimar las ventajas de algún código, solución o enfoque en particular. Y a menudo se llega a conclusiones muy extrañas... Extraños, pero justificados por mucha práctica.

Sólo comparto mi punto de vista.

 
Georgiy Merts:

La necesidad de la conversión surge porque el resultado de las operaciones con enteros y con coma flotante es significativamente diferente.

No puedo imaginar en qué situaciones no se puede hacer algo correctamente con los doblajes. En Lua (unido a quik), no hay tipos enteros en absoluto, sólo dubles, y nada.

 
pavlick_:

Tengo una mala idea de en qué situaciones no se puede hacer algo correctamente en los doblajes.

Contador.

void OnStart()
{
  const long Num1 = 9007199254967295;
  const long Num2 = Num1 + 1;

  Print(Num1 == Num2); // false
  Print((double)Num1 == (double)Num2); // true
}

doble no pierde toda la información de alcance, ya no tanto con el largo.

Особенности языка mql5, тонкости и приёмы работы
Особенности языка mql5, тонкости и приёмы работы
  • 2018.01.15
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql5, примеры решения тех, или иных задач...
 
fxsaber:

Contador.

Bueno, todavía hay que contar hasta ese número )). Y si realmente quieres, no es una opción:

double cnt;
double high_cnt;
if (++ cnt == 1 000 000) {
   ++ high_cnt;
   cnt = 0;
}
 
pavlick_:

Bueno, todavía hay que contar hasta ese número )). Pero si realmente quieres, no es una opción:

Es comprensible que se pueda torcer. Pero, ¿merece la pena?

En mi opinión, si la variable debe tener sólo valores enteros - debe ser entera sólo para hacer imposible escribir un valor de punto flotante en ella. El tipo de variable o valor de retorno en sí mismo ya contiene información importante sobre la variable y parcialmente sobre el algoritmo. Si utilizamos valores de punto flotante en todas partes, esta información se perderá.

E incluso el entero - dependiendo del algoritmo, en mi opinión - debe ser declarado como con signo o sin signo, y no necesariamente largo, sino tal vez "más corto" - sólo para que al mirar el código podamos entender inmediatamente qué rango de valores puede tener la variable en cuestión.

El hecho de que no haya valores enteros en Lua es, en mi opinión, una seria desventaja.