Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 143

 
Alexey Viktorov:

Semplicemente non dovreste aspettarvi che se non c'è un valore, è necessariamente 0 e corrispondentemente falso se non è una variabile di tipo bool. Anche una conversione esplicita in bool non aiuta.

Funziona così senza errori.

Onestamente non capisco affatto da dove viene lo zero:

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

TickValue[0] contiene spazzatura. Può essere o meno uguale a zero.

Se il cestino in TickValue[0] non è uguale a zero, allora calcoliamo Points = Profit / Lots * cestino non zero * _Point, altrimenti, se il cestino in TickValue[0] è uguale a zero - equipariamo Points a zero.

E da dove prende lo zero l 'espressione Lots * spazzatura non zero * _Point, se Lots è inizializzato con uno quando viene dichiarato? C'è zero in _Point?

 
fxsaber:

L'errore è chiaro infatti.

OK, l'errore non è chiaro. E non si riproduce nemmeno per me.

 
TheXpert:

Ok, l'errore è incomprensibile. E non si riproduce a me.

In parole povere, chiamare questa funzione può causare la divisione per zero.

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


Ho incontrato questo problema in pratica nella libreria Report. Poi ho capito che è logico.

 
fxsaber:

In parole povere, chiamare questa funzione può causare la divisione per zero.

Ho questo codice su border dubles, ma non va in crash

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:

Ottengo lo stesso codice su border dubles, ma non si blocca

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

void OnStart()
{
  double Num = 0;
  
  _W(Num) = (uchar)2;
  
  Print(WrongFunc(Num));
}
 
fxsaber:
una tale frangia.
 
TheXpert:
un tale incidente.

Per riassumere, la moltiplicazione di due doppietti non nulli può dare zero. E questo non è un caso degenerato, ma un caso reale nella pratica.

Approssimativamente, un EA da combattimento può rompersi a causa di questo con una probabilità tutt'altro che nulla.

 
E il controllo dello zero non salverà, né esplicitamente né implicitamente (conversione bool)
 
TheXpert:
E il controllo dello zero non salverà, né esplicitamente né implicitamente (conversione bool)
  return(0.1 * Num ? 1 / (0.1 * Num) : 0);
 
fxsaber:

Per riassumere, la moltiplicazione di due doppietti non nulli può dare zero. E questo non è un caso degenerato, ma un caso reale nella pratica.

Approssimativamente, un EA da combattimento può rompersi a causa di questo con una probabilità tutt'altro che nulla.

su NaN è necessario controllare ulteriormente, molto probabilmente questo codice funzioneràhttp://qaru.site/questions/20557/checking-if-a-double-or-float-is-nan-in-c

f != f

o limitare la precisione, come nell'esempio di CompareDoubles() - sembra essere in SBhttps://www.mql5.com/ru/docs/basis/types/double

Motivazione: