Erreurs, bugs, questions - page 2821

 
fxsaber:

Je répète ma question.

L'image montre la valeur de la variable non normalisée n et de la variable normalisée m et leur différence. Mais si vous voulez comparer les strings, c'est votre préférence.

fxsaber:

Je connais la théorie, comment travailler avec des doubles et des trucs comme ça sur une échelle A+. L'algorithme NormalizeDouble contient une erreur. Le sujet soulevé n'est qu'indirectement lié à la comparaison des doubles.

On ne peut définitivement pas se passer de l'explication de Semko ici.
 
NormalizeDouble est juste un certain algorithme qui s'applique à un nombre double. Malheureusement, il y a une erreur. Si elle est corrigée, l'erreur disparaîtra. La double représentation de tous les autres ne changera en rien.
 
fxsaber:

L'algorithme NormalizeDouble contient une erreur.

oui

Je pense que A100 a écrit à ce sujet

mais les développeurs depuis MQL s'en tiennent à cette "fonctionnalité", hélas


fxsaber:
S'ils la corrigent, l'erreur disparaîtra.
Je pense qu'il y aura d'autres bugs et qu'il y aura beaucoup de bruit )))).
 
Igor Makanu:

Je pense que d'autres bugs vont apparaître et qu'il y aura beaucoup de bruit )))).

Ils ne le feront pas, car presque tout le monde compare même les dubs normalisés par le biais de la normalisation. C'est-à-dire qu'ils le mettent où ils veulent.


Une normalisation correcte devrait toujours donner vrai dans cette condition.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Erreurs, bugs, questions

fxsaber, 2020.08.10 11:37

  Print((double)(string)Norm == Norm);    // false

C'est le seul moyen de vérifier que la normalisation est correcte. S'il donne toujours raison, rien ne se cassera.

 
fxsaber:
NormalizeDouble est juste un certain algorithme qui s'applique à un nombre double. Malheureusement, il y a une erreur. Si elle est corrigée, l'erreur disparaîtra. Toutes les autres doubles-représentations ne changeront pas en conséquence.
Je pense qu'il ne s'agit pas de la fonction, mais du fait que les constantes ne sont pas normalisées par le compilateur (alors qu'elles devraient l'être).
Il en va de même pour la conversion d'une chaîne en double.
 
Alexey Navoykov:
Je pense que ce n'est pas la fonction qui est en cause, mais le fait que les constantes ne sont pas normalisées par le compilateur (alors qu'elles devraient l'être).
Il en va de même pour la conversion de chaînes de caractères en doubles.

Alors les mêmes constantes dans DLL et MQL ne correspondront pas.

 
fxsaber:

Alors les mêmes constantes dans DLL et MQL ne correspondront pas.

C'est vrai aussi. De plus, toute normalisation est une perte de précision, donc je suis peut-être allé trop loin avec la normalisation des constantes.
D'une manière générale, ce problème n'a pas, à mon avis, de solution univoque, même si, en fait, ce n'est pas un tel problème.
 
Alexey Navoykov:
C'est vrai aussi. De plus, toute normalisation est une perte de précision, donc j'en fais probablement trop avec la normalisation constante.
D'une manière générale, ce problème ne me semble pas avoir de solution univoque, bien qu'il ne s'agisse pas d'un problème de fond.

Il suffit de modifier l'algorithme de normalisation actuel.

 
fxsaber:

Il suffit de modifier l'algorithme de normalisation actuel.

void OnStart() {
   double d1=1.79435;
   double d2=NormalizeDouble(1.79435,5);
   Print(d1==d2);
   Print(is_equal(d1,d2,_Point/2));
}
//+------------------------------------------------------------------+
bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}

Je ne sais même pas si c'est un bug dans l'algorithme.
Vraiment, vous ne pouvez pas comparer les doubles. C'est une règle stricte.
Ou, comme le dit Slava, par epsilon ou par multiplication (par exemple par 1/_Point) avec conversion en int avec arrondi.

Seul l'arrondi n'est pas effectué par round(), ceil(), floor() car ils retournent également un double.

Ou par ces derniers, d'autant plus qu'ils fonctionnent plus vite que les normaux :

int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;}
int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;}

Plus facile et plus rapide, bien sûr, grâce à epsilon :

bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}
 
Nikolai Semko:

Seul l'arrondi n'est pas effectué à l'aide des fonctions standard round(), ceil(), floor() car elles renvoient également un double.

Mais grâce à ceux-ci, surtout ils fonctionnent plus rapidement que les ordinaires :

C'est peut-être plus rapide, mais c'est tout simplement faux.
Passez quelque chose comme 12345.0000000000001 dans votre ceil (similaire à votre exemple), et vous pouvez obtenir 12346 dans la sortie.
Raison: