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

 
SK. писал (а):
VBAG:
Je ne m'attendais pas à ça de ta part.

Je retire ce que j'ai dit.
Heureux d'avoir eu tort dans mes doutes.
 

À SK.

Vous êtes le mieux placé pour le savoir. Je ne considère pas MQL comme un langage de programmation. C'est juste un tel DIALECT.

Au fait, j'en ai marre de deux choses dedans :

1) pas d'énumération des opérations, c'est-à-dire pas de crochets.

2) retour - vous êtes terriblement fatigué des parenthèses.

Dans l'ensemble, bien joué les gars.

Kernighan et Ritchie - un tonnerre d'applaudissements pour eux.

 
VBAG писал (а):
Je retire ce que j'ai dit.
Heureux d'avoir eu tort dans mes doutes.


Nous n'avons pas eu de dispute :)

Depfy:

Je ne considère pas MQL comme un langage de programmation. C'est juste un tel DIALECT.

C'est probablement une question de terminologie. Je trouve, par exemple, dans MQL tous les attributs d'un langage complet. En tout cas, c'est l'un des rares langages (notamment le meilleur) qui permet aux traders de mécaniser et d'automatiser leurs activités. Je pense que ce langage est tout à fait satisfaisant, au moins dans le sens où ses possibilités dépassent bien souvent les besoins de la plupart des algorithmes (en d'autres termes, s'il y avait suffisamment d'idées bien pensées et que les moyens de les mettre en œuvre étaient déjà disponibles).
 
SK. писал (а):
...

En l'état, la valeur initiale de la variable 123.00000000000 peut s'avérer être 122.99999999999999 au moment où elle est utilisée dans les calculs. Et ce, malgré le fait que depuis que la variable a été découverte, sa valeur n'a jamais changé, mais elle a seulement été sollicitée par le programme pour participer à d'autres calculs.


C'est en fait pourquoi il y a eu toute cette agitation. C'est pourquoi nous avons décidé d'utiliser NormalizeDouble() aussi près que possible du calcul réel, de préférence directement dans la condition des instructions if, for, while.

Etes-vous sûr de ce que vous dites ? Si vous pouvez préciser la source de vos connaissances ?

Alors j'ai cette question pour vous

1 ? si le problème est la mémorisation ou la lecture d'une variable, comment NormalizeDouble() peut-il aider si la valeur de retour est également mémorisée ou lue avec une erreur ?
2 ? pourquoi le schéma NormalizeDouble(value, digits) !OC ! NormalizeDouble(value, digits), où !OC ! - l'opérateur de comparaison ne fonctionne-t-il pas toujours ? même s'il est inséré directement dans if ?
3 ? Savez-vous comment fonctionne NormalizeDouble() (algorithme de la fonction) ?
4 ? j'ai écrit mon opinion sur ce sujet, qu'en pensez-vous ?

gravity001 a écrit (a) :

...
Je vous ai déjà parlé de la normalisation. Dites-moi d'abord pourquoi vous devez l'appliquer, puis comment et .

C'est la question clé, n'est-ce pas ? J'y pense moi-même depuis longtemps : "vous entrez double et vous obtenez double ". Qu'est-ce qui pourrait changer ?
Je n'ai pas trouvé la réponse exacte. Mais j'imagine que c'est comme ça

double a = 2.000000000000
double b = 2.000000000001
double c = 1.999999999999

Toutes ces variables sont différentes et sont stockées en mémoire avec une précision au dernier chiffre !
Dans ce cas, nous définissons nous-mêmes les signes (chiffres). Tout ce qui n'est pas défini est rempli de zéros.

Si nous avions défini double a = 2.0, et qu'il est stocké en mémoire sous la forme 2.0000001 ou 1.9999999, il est clair que NormalizeDouble() ne serait d'aucune utilité, car il renverrait une valeur inexacte !
Je pense qu'une telle erreur ne se produit presque jamais lors de la mémorisation d'une valeur variable. De plus, je ne pense pas que le nombre 2.0 soit stocké comme 1.99999999999999999 exprès, puisque chaque caractère (chiffre ou point) est stocké avec un bit spécifique dans la chaîne de bits ! Par conséquent, le nombre 2.0 est stocké en toute sécurité sous la forme 2.00000...00.

L'autre cas est celui où nous ne déterminons pas nous-mêmes les signes :

a = 4.0 ;
b = 2.0 ;
c = a / b // - l'opération de "division" est effectuée par le processeur, ou plutôt par le coprocesseur, et elle remplit le préambule avec des caractères (chiffres).

Après l'opération, il peut l'être :
Le plus souvent :
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

c'est-à-dire que le résultat diffère souvent de la valeur réelle par une petite quantité.

Les erreurs importantes sont très rares :
с = 2.3

Ici, il y a deux explications :
1) une partie de la chaîne de bits a été affectée en mémoire lors de l'appel de a ou b, c'est-à-dire que les variables a et b ont été modifiées.
2) une erreur s'est produite pendant l'opération de "division".

Je pense que le point 2) est le plus fréquent. Pourquoi je ne sais pas. Je pense que cela a à voir avec le fait que le coprocesseur est destiné à être hautement optimisé au détriment de l'inutilité.

Si l'on compare une variable au nombre 2.000...00, l'égalité échouera évidemment. Tous les bits ne seront pas égaux.

Maintenant, NormalizeDouble() est là pour vous aider !
NormalizeDouble() va "réparer" cette petite erreur !
L'erreur étant souvent très faible, l'arrondi avec une petite précision donnera toujours le résultat correct.

Voyez-le de cette façon :
Arrondissez le nombre a = 2,111...11 au deuxième chiffre.
NormalizeDouble() écrira 2.11 dans une nouvelle variable et remplira les bits restants avec des zéros, pas des uns !
Je pense que ça va ressembler à ça :

double MyNormalizeDouble(double value, int digits)
{
     int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                       с помощью которого мы из VALUE сделаем целое число
     double result = MathRound(factor * value) / factor;
     return(result);
}
Ici, j'ai fait de mon mieux pour expliquer pourquoi NormalizeDouble() est nécessaire.

Jusqu'à récemment, j'étais entièrement satisfait de cette explication, mais je me suis récemment convaincu que ce système ne fonctionne pas toujours.

NormalizeDouble(a, 2) ! NormalizeDouble(b, 2) où !OC ! - est un opérateur de comparaison.
Bien que, d'après ce que j'ai compris, cela doit toujours fonctionner !
Par conséquent, je serai heureux de recevoir toute critique raisonnée et compréhensible !
 
gravity001:
SK. a écrit (a) :
...

En l'état, la valeur initiale de la variable 123.00000000000 peut s'avérer être 122.99999999999999 au moment où elle est utilisée dans les calculs. Et ce, malgré le fait que depuis que la variable a été découverte, sa valeur n'a jamais changé, mais elle a seulement été sollicitée par le programme pour participer à d'autres calculs.

C'est en fait pourquoi il y a eu toute cette agitation. C'est pourquoi j'ai dû utiliser NormalizeDouble() aussi près que possible du calcul réel, de préférence directement dans la condition des instructions if, for, while.

Etes-vous sûr de ce que vous dites ? Si vous pouviez indiquer la source de vos connaissances ?
J'en suis sûr. La source de vos connaissances est votre propre expérience de la programmation MQL4 et les consultations de développeurs.
Si le problème réside dans la mémorisation ou la lecture d'une variable, comment NormalizeDouble() peut-il aider, si la valeur de retour est également mémorisée ou lue avec une erreur ?
NormalizeDouble() doit être appliqué immédiatement avant l'opération de comparaison. Le résultat de l'opération de comparaison est une valeur de type booléen, qui n'est jamais "corrompue".
2 ? pourquoi le schéma NormalizeDouble(value, digits) ! NormalizeDouble(value, digits) , où !OC ! est l'opérateur de comparaison, ne fonctionne pas toujours... Même si vous l'insérez directement dans if ?
Je n'ai pas dit ça. C'est exactement comme ça que ça marche et c'est ce que vous devriez faire.
3 ? Savez-vous comment fonctionne NormalizeDouble() (algorithme de la fonction) ?
Non, je ne le fais pas. Veuillez en référer aux développeurs.
4 ? J'ai écrit mon opinion sur ce sujet, qu'en pensez-vous ?
Votre opinion est intéressante, mais cette question a été résolue depuis longtemps. Il est préférable d'utiliser les recommandations des développeurs et de ne pas réinventer la roue.
 
SK. писал (а):
gravity001:

2. pourquoi le schéma NormalizeDouble(value, digits) !OC ! NormalizeDouble(value, digits) , où !OC ! est un opérateur de comparaison, ne fonctionne pas toujours, même si vous l'insérez directement dans if ?
Je n'ai pas dit ça. C'est exactement comme ça que ça marche et c'est comme ça que vous devriez le faire.

Voici d'autres avis sur ce sujet

Encore une fois sur la comparaison de deux doubles", 1 page du tout premier post !

Entier 24.12.2006 15:23

Malheureusement, la construction NormalizeDouble(x-y,Digits) n'est pas identique à la construction NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits).

Renat 24.12.2006 16:15

Et ça ne devrait pas être identique. La première est correcte.

Je pense que la construction est
si (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
et la construction
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sont identiques !

Qu'en pensez-vous ?
 
gravity001:

Renat 24.12.2006 16:15

Et elle ne doit pas être identique. La première est correcte.

Je pense que la construction
si(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
et la construction
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sont identiques !

Qu'en pensez-vous ?


Et l'opinion de Renat n'est pas intéressante ? L'opinion du PDG de l'entreprise qui développe MT ne vous intéresse pas ?

Ou êtes-vous comme la vieille femme dans le conte de fées de Pushkin ? Juste vouloir-vouloir-vouloir-vouloir ! Souvenez-vous de la fin de l'histoire. "Le poisson n'a rien dit. Il a remué la queue et s'est enfui dans la mer bleue. Il a attendu longtemps près de la mer pour une réponse. Il n'a pas attendu, il s'est retourné vers la vieille femme..."

 
SK. писал (а):
Lapremière est la gravité001:


Renat 24.12.2006 16:15

Et elle ne doit pas être identique. La première est correcte.

Je pense que la construction
si(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
et la construction
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
sont identiques !

Qu'en pensez-vous ?



Et l'opinion de Renat n'est pas intéressante ? L'opinion du PDG de l'entreprise qui développe MT ne vous intéresse pas ?


Ou êtes-vous comme la vieille femme dans le conte de fées de Pushkin ? Juste vouloir-vouloir-vouloir-vouloir ! Souvenez-vous de la fin de l'histoire. "Le poisson n'a rien dit. Il a remué la queue et s'est enfui dans la mer bleue. Il attendit longtemps une réponse au bord de la mer. Il n'a pas attendu, il s'est retourné vers la vieille femme..."



Donc, Renat a dit que la première façon est correcte et que la seconde est incorrecte, alors que vous avez dit que la seconde façon est correcte, n'est-ce pas ?

2 ? pourquoi le schéma NormalizeDouble(value, digits) !OC ! NormalizeDouble(value, digits) , où !OC ! est un opérateur de comparaison, ne fonctionne pas toujours, même si vous l'insérez directement dans if ?
Je n'ai pas dit ça. C'est exactement comme ça que ça marche, et c'est comme ça que ça devrait être fait.
 

Je l'ai dit dans le sens d'une comparaison plus ou moins poussée :

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))

ce qui signifie que les constructions de ce type ne fonctionnent pas toujours :

double a = NormalizeDouble(x,Digits);
double b = NormalizeDouble(y,Digits);
 
if (a > b)
  {
  ...
  }

Par exemple, NormalizeDouble() doit être inséré directement dans l'en-tête de l'opérateur, aussi près que possible de l'endroit où l'opération de comparaison est calculée.

Quant à l'avis des développeurs, je n'ai pas l'intention de le contester.

Et puis... ce fil de discussion traitait d'une construction entièrement différente :

 
SK. писал (а):

Je l'ai dit en impliquant une comparaison plus ou moins grande :

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))
Je n'ai pas vérifié le plus ou le moins, mais j'ai vérifié l'égalité.
J'ai eu des erreurs de comparaison lorsque j'ai utilisé cette construction :

if (NormalizeDouble(x, digits) == NormalizeDouble(y, digits))
{
    ...
}
Pourquoi, tu ne sais pas ?