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

 

Une conclusion étonnante ! Qu'est-ce qui vous fait penser cela avec n'importe quel chiffre, si vous ne "comprenez" même pas du tout ce qu'est un chiffre ?

 
Integer:

Une conclusion étonnante ! Qu'est-ce qui vous fait penser cela avec n'importe quel chiffre, si vous ne "comprenez" même pas du tout ce qu'est un chiffre ?

Tu commences à t'en prendre aux mots ? De toute évidence, il s'agira d'un assassinat de la personnalité. :)
Je dois dire tout de suite que je préfère ne pas participer à de telles explications, car si vous n'avez rien à dire sur le fond, pourquoi parler ?
 
VBAG:
J'aimerais remercier tous les professionnels pour leurs conseils !

Irtron, j'ai choisi votre variante, elle m'a beaucoup plu. Je l'ai corrigé un peu pour les cas généraux et je l'ai vérifié :

int ComparePrice(double a, double b, double chiffre)
{
a -= b ;
b = chiffre ;
si (a > b)
retour (1) ;
si (a < -b)
retour (-1) ;
retour (0) ;
}
Merci.
J'ai oublié de préciser que je veux passer n'importe quelle valeur prédéfinie dans le chiffre :
double digit14=0.00000000000001;
double chiffre12=0.000000000001 ;
double chiffre8=0.00000001 ;
double chiffre4=0.0001 ;
double chiffre2=0,01 ;
qui déterminera la précision requise.
Pour cette fonctionnalité, il fonctionne très rapidement.
Irtron, merci encore.

 
Irtron:
Entier:

Une conclusion étonnante ! Qu'est-ce qui vous fait penser cela avec n'importe quel chiffre, si vous ne "comprenez" même pas ce qu'est un chiffre ?

Tu commences à t'en prendre aux mots ? Évidemment, la prochaine étape sera un assassinat de personnalité. :)
Je dois dire tout de suite que je préfère ne pas participer à de telles explications, car si vous n'avez rien à dire sur le fond, pourquoi parler ?


Pourquoi chipoter, je viens de lire ce que vous avez écrit. Votre compréhension est manifestement entravée par "votre flagrante... (vous nommez le mot)"

VBAG, pourquoi réinventer la roue alors qu'il existe une fonction NormalizeDouble() qui compare deux nombres plus rapidement que ComparePrice() ?

 
Integer:

VBAG, pourquoi réinventer la roue alors qu'il existe une fonction NormalizeDouble() qui compare deux nombres plus rapidement que ComparePrice() ?

La fonction compare deux nombres doubles et donne la réponse <, > ou = avec 14 décimales (NormalizeDouble() est limité à 8 chiffres).
Si vous pouvez suggérer une moto similaire ou de meilleures solutions alternatives, je serai heureux de les utiliser.
Respectueusement,
Vladimir
 
VBAG:
Entier:

VBAG, pourquoi réinventer la roue alors qu'il existe une fonction NormalizeDouble() qui compare deux nombres plus rapidement que ComparePrice() ?

La fonction compare deux nombres doubles et donne la réponse <, > ou = avec 14 décimales (NormalizeDouble() est limité à 8 chiffres).
Si vous pouvez me suggérer une roue similaire ou de meilleures alternatives, je serai heureux de les utiliser.
Respectueusement,
Vladimir
Voici un test pour mon intérêt :
int start()
  {
//----
    double a = 1.23450001, b = 1.23449999;
 
    int start1 = GetTickCount(), c1;
    for ( c1 = 0; c1 < 100000000; c1 ++ ) CD( a, b,0.00000001);
    int end1 = GetTickCount();
    
 
    int start2 = GetTickCount(), c2;
    for ( c2 = 0; c2 < 100000000; c2 ++ )   xNormalize(a,b,8);
    int end2 = GetTickCount();
 
    Print( "CD: ", (end1-start1), ", xNormalize: ", (end2-start2) );
 
    return(0);
   }
 
//+ CompareDouble ---------------------------------------------------+ CompareDouble
int CD(double a, double b, double digit)
{
    a -= b;
    b = digit;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
// Две операции NormalizeDouble----
bool xNormalize(double a, double b,int digit)
  {
   double d1 = NormalizeDouble(a,digit);
   double d2 = NormalizeDouble(b,digit);
   
//   bool bCompare=d2-d1 > 0.0;
   bool bCompare= 0;
   return(bCompare);
2007.09.12 07:15:09 $CheckCompareDouble USDJPY,M5 : CD : 20485, xNormalize : 51265

Conclusion :
La fonction CD compare deux nombres doubles, donne la réponse <, > ou = avec 14 décimales et fonctionne 2 fois plus vite que la simple exécution de NormalizeDouble() (même sans logique pour les comparer).
 
Oui, deux appels à NormalizeDouble() prennent plus de temps que CD, et un appel est plus rapide. La précision de 14 chiffres est une bonne chose :-)
 
J'ai essayé de comparer les chiffres réels récemment aussi !

Beaucoup de gens écrivent que pour la comparaison il faut utiliser la fonction intégrée NormalizeDouble(). (c'est aussi ce que les développeurs recommandent).
Par conséquent, je voudrais d'abord définir : "Qu'est-ce que NormalizeDouble() ?", c'est-à-dire comment il fonctionne, quel est son algorithme.

Référence MQL4 - Conversions de données - NormalizeDouble

Arrondir un nombre à virgule flottante à une précision spécifiée.
...

Je ne sais pas comment l'arrondi est organisé dans MQL4 (demandez aux développeurs), mais je connais une méthode standard Arrondir les nombres à virgule flottante à la précision spécifiée :
Ici, une fonction :

double MyNormalizeDouble(double value, int digits)
{
    int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                      с помощью которого мы из VALUE сделаем целое число
    double result = MathRound(factor * value) / factor;
    
    return(result);
}
Cette fonction montre que l'on passe d'abord d'un nombre réel à un nombre entier, puis que l'on revient à un nombre réel.
Pour la comparaison, il suffit de passer à un nombre entier.

Par conséquent, je pense que le moyen le plus rapide et le plus fiable de comparer des nombres réels est de les convertir en nombres entiers.
Voici à quoi ressemblera la comparaison :

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

Tout cela peut être mis en forme dans une fonction et utilisé. C'est une douleur d'écrire, il semble être clair comment faire une fonction !
Je pense que cette méthode est plus rapide que d'appeler NormalizeDouble().

Par sécurité, vous pouvez également faire en sorte que la fonction MathRound() renvoie un nombre entier, puisque par défaut elle renvoie un double.
La façon la plus simple de procéder est la suivante

int MyMathRound(double value)
{
    int result = MathRound(value);
    return(result);
}
Alors seuls les entiers seront comparés, et ils se comparent bien !


Je pense que cette façon est la plus correcte, n'est-ce pas ?
 
gravity001:

Je pense donc que le moyen le plus rapide et le plus fiable est de convertir les nombres réels en nombres entiers.
La comparaison ressemblerait à ceci :

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

Je pense que c'est la bonne façon de faire, n'est-ce pas ?

Je ne pense pas. Jugez-en par vous-même :
Toute la beauté du code d'Irtron réside dans sa compacité (absolument rien de supplémentaire - même les variables sont sauvegardées !)
Et vous suggérez que nous devrions ajouter deux opérations supplémentaires pour chaque opération
(а - b)
au moins.
(MathRound( (а - b) * factor ) 
C'est un avantage en termes de vitesse !
 
VBAG:
Je ne pense pas. Jugez par vous-même

Oui, un peu plus lentement :
int start()
{
    double a, b;
    int start1, start2, end, c;
    
    a = 1.23450001;
    b = 1.23449999;
    
    start1 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        ComparePrice(a, b,0.0001);
    
    start2 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        intCompare(a, b,10000);
    
    end = GetTickCount();
 
    Print("ComparePrice: ", start2 - start1, ", intCompare: ", end - start2);
 
    return(0);
}
 
int ComparePrice(double a, double b, double point)
{
    a -= b;
    b = point / 2.;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
int intCompare(double a, double b, int factor)
{
    return(MathRound( (a-b) * factor ));
}
ComparePrice : 32032, intCompare : 35296
Raison: