Question aux maîtres du MQL4. Encore une fois à propos de Double Comparaison.

 
Bonjour !
Comme vous le savez, non seulement l'exactitude des calculs mais aussi la fiabilité du code écrit dépendent du style de programmation et de la propreté du code.
Nous n'écrivons pas de jouets, la fiabilité du programme écrit est donc la toute première exigence. La plupart des calculs sont effectués en dubles et une comparaison correcte dans le code du
de deux nombres réels dans le code du programme nécessite une certaine approche et précision.
J'essaie de trouver le "bon" style de programmation, d'où ma question :

Pour une expression

double a ;
double b ;

si(a==b) ou si(a!=b)
{......} {......}

Les développeurs recommandent ce qui suit
//+------------------------------------------------------------------+
//| Fonction de comparaison de deux nombres réels. | |
//+------------------------------------------------------------------+
bool CompareDouble(double Nombre1, double Nombre2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0 ;
retour(Compare) ;
}
//+------------------------------------------------------------------+


Ce code est-il correct ?

double a ;
double b ;

si(a>b) si(a<b)
{......} {......}


Très probablement pas dans le cas général. Quelle est la manière correcte de le vérifier ?
En général, quel style de travail avec les dubles est le plus approprié ?
Merci d'avance à tous ceux qui répondent.
 

Je préfère, dans la mesure du possible, utiliser les chiffres les plus grands et les plus petits pour la comparaison,

double a;
double b;
 
if(a>b)             if(a<b)
    {......}            {......}

pour que je n'aie pas à me préoccuper de doubler un certain chiffre

Vol = 156.00000002; 
NormVol = NormalizeDouble(Vol,2); 
156.00

S'il est nécessaire de rassembler les chiffres

if(a==b)    или         if(a!=b)
    {......}                    {......}

alors je convertis d'abord les deux nombres en un seul chiffre après le point

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......}
 
xeon:

Je convertis d'abord les deux nombres en un même chiffre après le point.

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
Et lorsque vous calculez dans les indicateurs, utilisez-vous Normalize et des préparations similaires ?
Je regarde beaucoup de code, j'apprends à programmer et on le trouve rarement dans le code de l'indicateur. Telle est la question - comment le faire correctement.
 
VBAG:
xeon:

Je convertis d'abord les deux nombres en un même chiffre après le point.

  a = NormalizeDouble(Vol1,2);
  b = NormalizeDouble(Vol2,2);
if(a==b)    или         if(a!=b)
    {......}                    {......} 
Utilisez-vous Normalize et des préparations similaires dans vos calculs d'indicateurs ?
Je regarde beaucoup de code, j'apprends à programmer et on le trouve rarement dans le code de l'indicateur. Telle est la question - comment le faire correctement.

J'essaie de l'éviter en utilisantNormalizeDouble ou les signes "<" et ">", car l'indicateur, le script ou l'Expert Advisor peut avoir des divergences dans le double.
 
xeon ,
Merci pour votre opinion.
 
Normaliser toujours et il n'y aura jamais de problème avec les dubs ! ;)
Dans n'importe quelle comparaison, n'importe quel tâtonnement, et avec une précision délibérément choisie.

//--- NormalizeDouble
double nd( double value, int precision )
{
    return( NormalizeDouble( value, precision ) );
}
 
//--- MathAbs
double abs( double value )
{
    return( MathAbs( value ) );
}
 
//--- Если value1 равняется value2 до precision знака после запятой, возвращает true, иначе - false.
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( nd( value1, precision ) - nd( value2, precision ) ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}

Faites attention à la fonction d'égalité - si elle est légèrement modifiée :
bool equal( double value1, double value2, int precision = 8 )
{
    return( nd( abs( value1 - value2 ), precision ) < nd( MathPow( 0.1, precision ), precision ) );
}
(supprimer la normalisation de chaque nombre avant la comparaison), cela donnera un résultat différent.

Par exemple, equal( 0.123456784, 0.123456776 ) retournera vrai dans le premier cas, mais faux dans le second ;)
 
komposter:
Normaliser toujours et il n'y aura jamais de problème avec les dubs ! ;)
Mais il y aura des problèmes de performance. Le problème de la comparaison des chiffres en double précision est tiré par les cheveux et provient d'une ignorance fondamentale des mathématiques.
 
Irtron:
Le problème de la comparaison des chiffres en double précision est tiré par les cheveux et provient d'une ignorance fondamentale des mathématiques.

Laissez-moi vous expliquer.

Il y a manifestement une confusion de notions. Il existe un type de nombre à virgule flottante utilisé dans l'architecture intel pour représenter les nombres à précision fixe, qui comprennent notamment toutes les valeurs de l'environnement de négociation, car le processeur dispose d'un batteur spécial pour l'arithmétique à virgule flottante.

En fait, les nombres à précision fixe diffèrent très peu des entiers en termes de représentation par la machine. La présence d'une décimale dans ce cas est conditionnelle. Cette propriété est largement utilisée dans les architectures où l'arithmétique à virgule flottante n'est pas prise en charge par le matériel, comme l'ARM, qui s'est répandue par son utilisation dans les PDA et les smartphones. L'arithmétique flottante doit être émulée avec un code assez lourd, ce qui fait chauffer le processeur et gaspille la batterie, sans parler de la vitesse d'exécution du programme. Ainsi, chaque fois qu'il n'est pas possible de le faire avec des entiers, un format fixe est utilisé. La précision flottante est utilisée dans les cas les plus extrêmes. Ou plutôt, bien sûr, il devrait l'être.

Rien n'empêche d'utiliser une arithmétique fixe (c'est-à-dire entière) pour les valeurs marchandes.

Ceci ne s'applique pas aux valeurs calculées des indicateurs. Une comparaison directe est tout à fait suffisante dans ce cas. Pourquoi les comparer avec une quelconque précision ?
 
Merci à komposter et Irtron ! J'ai déjà décidé que je n'écrirai plus rien, je me suis assis pour m'inventer et je n'ai pas vu vos messages.
Veuillez voir ce que j'ai écrit avec ma propre main rusée :
//+------------------------------------------------------------------+
bool EqualDouble(double dN1, double dN2,int Digit)
{
double d1 = NormalizeDouble(dN1,Digit) ;
double d2 = NormalizeDouble(dN2,Digit) ;
bool res=false ;
res=d1-d2 == 0.0 ;
return(res) ;
}
//+------------------------------------------------------------------+
bool LessDouble(double dN1, double dN2,int Digit) // Si dN1<dN2
{
double d1 = NormalizeDouble(dN1,Digit) ;
double d2 = NormalizeDouble(dN2,Digit) ;
bool res=false ;
res=d2-d1 > 0.0 ;
return(res) ;
}
//+------------------------------------------------------------------+
bool MoreDouble(double dN1, double dN2,int Digit) // Si dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit) ;
double d2 = NormalizeDouble(dN2,Digit) ;
bool res=false ;
res=d1-d2 > 0.0 ;
return(res) ;
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
 
VBAG:
S'il vous plaît, voyez ce que j'ai griffonné de ma main négligente :
Quelles sont les valeurs que vous essayez de comparer ? Prix, lots ou valeurs indicatives ?
 
Irtron:
VBAG:
Jetez un coup d'œil à ce que j'ai griffonné de ma main négligente :
Quelles sont les valeurs que vous essayez de comparer ? Prix, lots ou valeurs indicatives ?
J'ai écrit au début : "Essayer de trouver le 'bon' style de programmation. "
En substance, le contenu des dubles ne fait aucune différence - seule la précision de l'arrondi des chiffres varie, en fonction des exigences de la variable.
Raison: