Caractéristiques du langage mql5, subtilités et techniques - page 143

 
Alexey Viktorov:

Il ne faut pas s'attendre à ce que s'il n'y a pas de valeur, elle soit nécessairement 0 et donc fausse s'il ne s'agit pas d'une variable de type bool. Même une conversion explicite en bool ne sera d'aucune utilité.

Il fonctionne de cette manière sans erreur.

Honnêtement, je ne comprends pas du tout d'où vient le zéro :

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

TickValue[0] contient des déchets. Il peut être égal ou non à zéro.

Si la corbeille dans TickValue[0] n'est pas égale à zéro, alors nous calculons Points = Profit / Lots * corbeille non-zéro * _Point, sinon, si la corbeille dans TickValue[0] est égale à zéro - nous mettons les Points à zéro.

Et où l'expression Lots * non-zéro rubbish * _Point obtient-elle zéro, si Lots est initialisé avec un lors de sa déclaration ? Y a-t-ilun zéro dans _Point?

 
fxsaber:

L'erreur est claire dans les faits.

OK, l'erreur n'est pas claire. Et ça ne se reproduit pas pour moi non plus.

 
TheXpert:

Ok, l'erreur est incompréhensible. Et ça ne se reproduit pas sur moi.

En gros, l'appel de cette fonction peut provoquer une division par zéro.

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


J'ai rencontré ce problème en pratique dans la bibliothèque de rapports. Puis j'ai réalisé que c'est logique.

 
fxsaber:

En gros, l'appel de cette fonction peut provoquer une division par zéro.

J'ai ce code sur border dubles, mais il ne se plante pas

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:

J'obtiens le même code sur les dubles frontaliers, mais il ne se plante pas

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

void OnStart()
{
  double Num = 0;
  
  _W(Num) = (uchar)2;
  
  Print(WrongFunc(Num));
}
 
fxsaber:
un tel dégoût.
 
TheXpert:
un tel accident.

En résumé, la multiplication de deux doublets non nuls peut donner zéro. Et il ne s'agit pas d'un cas dégénéré, mais d'un cas réel dans la pratique.

En gros, un EA de combat peut se casser à cause de cela avec une probabilité loin d'être nulle.

 
Et la vérification du zéro ne permet pas de sauvegarder, que ce soit explicitement ou implicitement (conversion bool).
 
TheXpert:
Et la vérification du zéro ne permet pas de sauvegarder, que ce soit explicitement ou implicitement (conversion bool).
  return(0.1 * Num ? 1 / (0.1 * Num) : 0);
 
fxsaber:

En résumé, la multiplication de deux doublets non nuls peut donner zéro. Et il ne s'agit pas d'un cas dégénéré, mais d'un cas réel dans la pratique.

En gros, un EA de combat peut se casser à cause de cela avec une probabilité loin d'être nulle.

sur NaN vous devez vérifier en plus, très probablement ce code fonctionnerahttp://qaru.site/questions/20557/checking-if-a-double-or-float-is-nan-in-c

f != f

ou limiter la précision, comme dans l'exemple de CompareDoubles() - il semble être dans SBhttps://www.mql5.com/ru/docs/basis/types/double.