Características del lenguaje mql5, sutilezas y técnicas - página 143

 
Alexey Viktorov:

Simplemente no debes esperar que si no hay valor, sea necesariamente 0 y correspondientemente falso si no es una variable de tipo bool. Incluso una conversión explícita a bool no ayudará.

Funciona así sin errores.

Sinceramente, no entiendo de dónde sale el cero en absoluto:

const double Points = TickValue[0] ? Profit / (Lots * TickValue[0] * _Point) : 0; // zero divide

TickValue[0] contiene basura. Puede o no ser igual a cero.

Si la basura en TickValue[0] no es igual a cero, entonces calculamos Puntos = Beneficio / Lotes * basura no nula * _Punto, de lo contrario, si la basura en TickValue[0] es igual a cero - igualamos Puntos a cero.

¿Y de dónde saca el cero la expresión Lots * basura no nula * _Point, si Lots se inicializa con uno cuando se declara? ¿Hay un cero en _Punto?

 
fxsaber:

El error es claro de hecho.

Bien, el error no está claro. Y a mí tampoco me reproduce.

 
TheXpert:

Vale, el error es incomprensible. Y no se reproduce en mí.

A grandes rasgos, llamar a esta función puede provocar una división por cero.

// Неправильно написанная функция.
double WrongFunc( const double Num )
{
  return(Num ? 1 / (0.1 * Num) : 0);
}


Me encontré con este problema en la práctica en la biblioteca de informes. Entonces me di cuenta de que es lógico.

 
fxsaber:

A grandes rasgos, llamar a esta función puede provocar la división por cero.

Tengo este código en los doblajes de la frontera, pero no se bloquea

double f( const double Num )
{
  return(Num ? 1 / (0.1 * Num) : 0);
}

void OnStart()
{
  Print(f(1 e-308));  // 2019.10.28 13:02:19.457	test (USDJPY,H1) inf
}
 
TheXpert:

Me sale el mismo código en los doblajes de la frontera, pero no se bloquea

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

void OnStart()
{
  double Num = 0;
  
  _W(Num) = (uchar)2;
  
  Print(WrongFunc(Num));
}
 
fxsaber:
un gran desplante.
 
TheXpert:
tal choque.

En resumen, la multiplicación de dos dobletes no nulos puede dar cero. Y no se trata de un caso degenerado, sino de uno real en la práctica.

A grandes rasgos, un EA de combate puede romperse por este motivo con una probabilidad muy alejada de cero.

 
Y la comprobación de cero no se guardará, ni explícita ni implícitamente (conversión bool)
 
TheXpert:
Y la comprobación de cero no se guardará, ni explícita ni implícitamente (conversión bool)
  return(0.1 * Num ? 1 / (0.1 * Num) : 0);
 
fxsaber:

En resumen, la multiplicación de dos dobletes no nulos puede dar cero. Y no se trata de un caso degenerado, sino de uno real en la práctica.

A grandes rasgos, un EA de combate puede romperse por este motivo con una probabilidad muy alejada de cero.

en NaN es necesario comprobar adicionalmente, lo más probable es que este código funcionehttp://qaru.site/questions/20557/checking-if-a-double-or-float-is-nan-in-c

f != f

o limitar la precisión, como en el ejemplo de CompareDoubles() - parece estar en SBhttps://www.mql5.com/ru/docs/basis/types/double