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

 
SK. писал (а):

Cette conversation semble se poursuivre indéfiniment. Lorsqu'un nouvel utilisateur a acquis l'expérience et les connaissances nécessaires, il a généralement le temps de se heurter plusieurs fois à la normalisation.

Dans MT5, il serait peut-être judicieux de limiter de force la précision des nombres réels lors des opérations de comparaison, par exemple à 8 décimales (c'est-à-dire d'exécuter de force NormalizeDouble() avec digit=8).

Je ne m'attendais pas à ça de ta part. Absolument pas !
Si l'opération de comparaison est utilisée de manière répétée (dans des calculs récurrents, etc.), alors en arrondissant à 8 chiffres en entrée, l'erreur en sortie peut être proportionnelle à 1.

J'ai eu une telle expérience avec le calcul de SmoothedAvarege, en le calculant dans mon application il y a un an. Après cela, j'essaie de choisir des méthodes de travail qui n'affectent pas la capacité digitale des doubles.
Ou, comme l'a suggéré gravity001 , passer à INTam (qui, comme vous le comprenez, prend beaucoup de temps).
 
SK. писал (а):

Dans MT5, il serait peut-être judicieux de limiter de force la précision des nombres réels lors des opérations de comparaison à, disons, 8 décimales (c'est-à-dire d'exécuter de force NormalizeDouble() avec digit=8).


Cependant, non seulement les opérations définies par l'utilisateur ralentissent le terminal, mais aussi les opérations qui lui sont cachées. Il me semble préférable d'introduire simplement la fonction ComparePrice dans le langage. Au fait, tout comme Irtron, je considère que Point/2 est une mesure naturelle (peut-être mieux Point *0,5). Pour éviter de diviser/multiplier à chaque fois, on peut faire de cette moitié une variable prédéfinie. Jusqu'à ce que cela n'existe pas, vous pouvez saisir vous-même une telle variable et la calculer une fois au premier démarrage. Cependant, les développeurs peuvent créer une fonction de double comparaison avec une précision prédéfinie, c'est-à-dire la même chose, mais avec des chiffres au lieu de Point/2.
 
Depfy:

Vous avez fait un gâchis... :)

La comparaison des nombres flottants se fait en comparant le module de la différence avec un petit seuil.

Retourner (fabs(d1-d2) < 1e-10) par exemple.

Quel est l'intérêt de brouiller les pistes... La fonction NormalizeDouble(...) ne sert qu'à produire de beaux rapports.

Merci pour l'exemple.
Mais vous passez à côté de l'essentiel, vous devez lire plus attentivement. L'essence de la question est le style de programmation en général, et dans le cas spécifique de MT4.
 
VBAG:
Depfy:

Vous avez fait un gâchis... :)

La comparaison des nombres flottants se fait en comparant le module de la différence avec un petit seuil.

Retourner (fabs(d1-d2) < 1e-10) par exemple.

Quel est l'intérêt de brouiller les pistes... La fonction NormalizeDouble(...) ne sert qu'à produire de beaux rapports.

Merci pour l'exemple.
Mais vous passez à côté de l'essentiel, vous devez lire plus attentivement. L'essence de la question est le style de programmation en général, et dans le cas spécifique de MT4.

Vous feriez mieux de nous dire quel est le but de cette question. Sinon des conseils - je ne comprends pas :)

Si l'on parle de vitesse, les processeurs modernes effectuent des opérations à virgule flottante

presque aussi vite que les entiers. Quant au STYLE, désolé, le pragmatisme est de rigueur...

Quand les ASHIPS sont là, de quel genre de style parlons-nous... Du moment que ça marche. ...

Sinon, il n'y a pas d'autre problème que de comparer deux nombres : )))))))).

 
VBAG:
Je ne m'attendais pas à une telle chose de ta part. Vous ne devez pas faire ça en tout cas !
Si l'opération de comparaison est utilisée de manière répétée (dans des calculs récurrents, etc.), alors en arrondissant à 8 chiffres en entrée, l'erreur en sortie peut être proportionnelle à 1.

J'ai eu une telle expérience avec le calcul de SmoothedAvarege, en le calculant dans mon application il y a un an. Après cela, j'essaie de choisir des méthodes de travail qui n'affectent pas la capacité digitale des doubles.
Ou, comme l'a suggéré gravity001 , passer à INTam (qui, comme vous le comprenez, prend beaucoup de temps).


Attendez une minute. Il n'est pas nécessaire de tirer des conclusions hâtives.

Tout d'abord. Je ne propose pas d'arrondir de force la valeur réelle de la variable réelle elle-même. Je propose de forcer l'arrondi des valeurs comparées (copies) des variables lors du calcul du résultat d'une opération de comparaison (pour le cas par défaut). Et bien sûr, la valeur réelle de la variable ne doit pas être touchée. Dans ce cas, aucune autre valeur calculée ne serait affectée, car les valeurs originales des variables utilisées dans les opérations de comparaison conservent leurs valeurs, et les erreurs dans les calculs cycliques ne s'accumulent pas.

Deuxièmement. J'ai dit qu'afin d'éliminer les erreurs aux conséquences plus sévères, nous pouvons procéder de cette manière. Cependant, afin de fournir également des calculs plus exigeants, il est nécessaire de conserver la possibilité d'utiliser la fonctionNormalizeDouble() avec des paramètres spécifiés.

Ma suggestion ne limite donc pas les capacités du langage, mais les étend.

Toutefois, si l'on tient compte du fait que, dans les opérations de comparaison, on utilise en règle générale des valeurs de prix (c'est-à-dire chiffre = 4), cette erreur ne se produira tout simplement pas dans la grande majorité des cas. Ainsi, l'utilisation de la technologie proposée réduira le nombre d'erreurs qui entraînent des conséquences imprévisibles.

 
lna01:
Et si cela n'est pas disponible, vous pouvez entrer une telle variable et la calculer une fois au premier démarrage.

Tu ne peux pas.

Ou plutôt, vous pouvez écrire des chaînes de programmes, mais personne (y compris les développeurs) ne garantira que la valeur de cette variable restera strictement inchangée pendant toute la durée de vie de l'EA. Il ne s'agit pas de la précision du code du programme, mais des caractéristiques technologiques des calculs et des règles technologiques de stockage des valeurs des variables. Si ce n'était pas le cas, ce problème n'existerait même pas.

Dans l'état actuel des choses, la valeur initiale de la variable 123.00000000000 peut apparaître comme 122.99999999999999 au moment où elle est utilisée dans les calculs. Et ce, malgré le fait que la valeur de la variable n'a jamais changé depuis sa création et qu'elle n'a été appelée par le programme que pour participer à d'autres calculs.

C'est en fait pourquoi il y a eu toute cette agitation. C'est pourquoi nous avons créé la nécessité 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.

 
SK. писал (а):
lna01:
Et si cela n'est pas disponible, vous pouvez saisir vous-même une telle variable et la calculer une fois lors du premier démarrage.

Tu ne peux pas.

Ou plutôt, vous pouvez écrire des chaînes de programmes, mais personne (y compris les développeurs) ne garantira que la valeur de cette variable restera strictement inchangée pendant toute la durée de vie de l'EA. Il ne s'agit pas de la précision du code du programme, mais des caractéristiques technologiques des calculs et des règles technologiques de stockage des valeurs des variables. Si ce n'était pas le cas, ce problème n'existerait même pas.

Dans l'état actuel des choses, la valeur initiale de la variable 123.00000000000 peut apparaître comme 122.99999999999999 au moment où elle est utilisée dans les calculs. Et ce, malgré le fait que la valeur de la variable n'a jamais changé depuis sa création et qu'elle n'a été appelée par le programme que pour participer à d'autres calculs.

C'est en fait pourquoi il y a eu toute cette agitation. C'est pourquoi j'avais besoin 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.

Bon sang, je crois que je commence à comprendre pourquoi on en fait tout un plat...

En somme, je suppose que vous n'avez pas besoin d'inventer quoi que ce soit. Tout dépend de la situation. Quel est l'objectif ? Si deux nombres peuvent différer en mantisse 0.1, et si c'est CRITIQUE, c'est une chose, si ce n'est pas important, c'en est une autre. Cela dépend de ce que l'on compare entre eux. Mais la FLEXIBILITÉ, donnée par un VRAI compilateur sans fioritures, est une chose VRAIE et nécessaire, IMHO.

:)

 
SK. писал (а):
Il ne s'agit pas ici de l'exactitude du code du programme, mais des caractéristiques technologiques des calculs et des règles technologiques de stockage des valeurs variables. Si ce n'était pas le cas, la question ne se serait même pas posée.
C'est vrai pour les calculs, mais il me semblait que tout devait être meilleur avec le stockage. Et lorsque les chiffres = 4, la différence du 15e chiffre ne devrait pas jouer de rôle.
 
Depfy:

Bon sang, je crois que je commence à comprendre pourquoi on en fait tout un plat...

D'une manière générale, je ne pense pas qu'il y ait quoi que ce soit à inventer. Parce que tout dépend de la situation. Quel est l'objectif ? Si deux nombres peuvent différer en mantisse 0.1, et si c'est CRITIQUE, c'est une chose, si ce n'est pas important, c'en est une autre. Cela dépend de ce que l'on compare entre eux. Mais la FLEXIBILITÉ, donnée par un VRAI compilateur sans fioritures, est une chose VRAIE et nécessaire, IMHO.

:)


Je ne peux pas répondre à la question "inventer". Apparemment, cela dépend de ce à quoi vous pensez :)

Par exemple, des inventions comme Point/2 permettent réellement d'effectuer des calculs avec une certaine précision dans certains cas. Cependant, il est préférable d'utiliser la recommandation des développeurs, à savoir prendre pour règle, une fois pour toutes (jusqu'à la nouvelle documentation), d'utiliser la fonction NormalizeDouble() lors du calcul des opérations de comparaison.

 
lna01:
SK. a écrit (a) :
Il ne s'agit pas ici de l'exactitude du code du programme, mais des caractéristiques technologiques des calculs et des règles technologiques de stockage des valeurs variables. Si ce n'était pas le cas, la question ne se serait même pas posée.
C'est vrai pour les calculs, mais je pensais que ce serait mieux pour le stockage. Et avec des chiffres = 4, la différence dans le 15ème chiffre ne devrait pas avoir d'importance.

Et cela n'aura aucune importance si vous utilisez NormalizeDouble(). Et si vous ne l'utilisez pas, c'est une question de chance.
Raison: