Si c'est pour la comparaison, vous pourriez facilement créer votre propre fonction :
bool checkDoubles(double a, double b, string check)
{
if(check==">"){
if (a - b > Point / 2)return(1);elsereturn (0);
}elseif(check=="<"){
if (b - a > Point / 2)return(1);elsereturn (0);
}elseif(check==">="){
if (a - b > -Point)return(1);elsereturn (0);
}if(check=="<="){
if (b - a > -Point)return(1);elsereturn (0);
}elseif(check=="!="){
if (MathAbs(a - b) > Point / 2)return(1);elsereturn (0);
}else {
Print("Sorry you've entered a wrong check value");
}
return (0);
}
L'utilisation de "Point" ou "Point/2.0" n'est pas une très bonne valeur de différence, IMO. L'erreur d'arrondi introduite par NormalizeDouble (qui m'a brûlé aujourd'hui), est certainement beaucoup plus petite que 8 chiffres, plus probablement 15 chiffres.
Compte tenu des conseils précédents, j'ai apporté quelques modifications et mis au point la routine suivante qui semble fonctionner correctement (même en utilisant la "différence" à 15 décimales), bien qu'elle n'ait pas encore été rigoureusement testée :
//+------------------------------------------------------------------+bool AvsB(double A, string checkStr, double B)
{
//checkStr = StringTrimLeft(StringTrimRight(checkStr));
double diff = 0.000000000000001; // 15 decimal places//double diff = 0.000000005;//double diff = 0.00000001;if (checkStr == ">" ){if (A - B > diff)return(true);elsereturn(false);}
elseif(checkStr == "<" ){if (B - A > diff)return(true);elsereturn(false);}
elseif(checkStr == ">="){if (A - B > -diff)return(true);elsereturn(false);}
elseif(checkStr == "<="){if (B - A > -diff)return(true);elsereturn(false);}
elseif(checkStr == "!="){if (MathAbs(A - B) > diff)return(true);elsereturn(false);}
elseif(checkStr == "=" || checkStr == "=="){if (MathAbs(A - B) < diff)return(true);elsereturn(false);}
else {Print("Sorry, bad usage: AvsB(A, checkStr, B). Wrong checkStr value: ",checkStr);}
return(false);
} // end of AvsB//+------------------------------------------------------------------+
Here is a check of the obvious:
if (1.34929 == NormalizeDouble(1.34929 , 5)) Alert("MT4 Pass");
elseAlert("MT4 FAIL. ROUNDOFF BUG"); // Yes, this is what MT4 does, a fail.if (AvsB(1.34929 ,"==", NormalizeDouble(1.34929 , 5))) Alert("AvsB Pass"); // It does pass using the AvsB routine!elseAlert("AvsB FAIL. ROUNDOFF BUG");
Voici encore une autre routine possible qui peut comparer, mais qui peut aussi normaliser en interne soit A et/ou B, et qui va aussi relaxer la différence de comparaison (de A-B ou B-A) à un nombre plus grand basé sur les "chiffres". Je doute que cette routine soit nécessaire par rapport à la simple "AvsB" ci-dessus, mais elle est proposée à votre usage si vous le souhaitez :
//+------------------------------------------------------------------+bool AvsB_nA_nB_digits(double A, string checkStr, double B, bool normalizeA, bool normalizeB, int digits)
{
//checkStr = StringTrimLeft(StringTrimRight(checkStr));
if (normalizeA) A = NormalizeDouble(A,MathMin(8,digits));
if (normalizeB) B = NormalizeDouble(B,MathMin(8,digits));
double diff;
switch(digits)
{
case0 : diff = 0.5; break; // Or 1.0 ??case1 : diff = 0.1; break;
case2 : diff = 0.01; break;
case3 : diff = 0.001; break;
case4 : diff = 0.0001; break;
case5 : diff = 0.00001; break;
case6 : diff = 0.000001; break;
case7 : diff = 0.0000001; break;
case8 : diff = 0.00000001; break;
case9 : diff = 0.000000001; break;
case10 : diff = 0.0000000001; break;
case11 : diff = 0.00000000001; break;
case12 : diff = 0.000000000001; break;
case13 : diff = 0.0000000000001; break;
case14 : diff = 0.00000000000001; break;
default : diff = 0.000000000000001; break; // 15 decimal places max (I think)
}
if (checkStr == ">" ){if (A - B > diff)return(true);elsereturn(false);}
elseif(checkStr == "<" ){if (B - A > diff)return(true);elsereturn(false);}
elseif(checkStr == ">="){if (A - B > -diff)return(true);elsereturn(false);}
elseif(checkStr == "<="){if (B - A > -diff)return(true);elsereturn(false);}
elseif(checkStr == "!="){if (MathAbs(A - B) > diff)return(true);elsereturn(false);}
elseif(checkStr == "=" || checkStr == "=="){if (MathAbs(A - B) < diff)return(true);elsereturn(false);}
else {Print("Sorry, bad usage: AvsB(A, checkStr, B). Wrong checkStr value: ",checkStr);}
return(false);
} // end of AvsB_nA_nB_digits//+------------------------------------------------------------------+
L'utilisation de "Point" ou "Point/2.0" n'est pas une très bonne valeur de différence, IMO. L'erreur d'arrondi introduite par NormalizeDouble (qui m'a brûlé aujourd'hui), est certainement beaucoup plus petite que 8 chiffres, plus probablement 15 chiffres.
Vous voulez la plus grande valeur qui ne peut pas être considérée comme une erreur d'arrondi ou, de manière équivalente, la plus petite valeur qui ne peut pas être considérée comme un changement de prix. Puisque les prix ne peuvent changer que d'un multiple de point, point/2 est exactement cela.
La valeur double du courtier pourrait être n'importe où entre 1,23457500000000 et 1,23458499999999999 et être toujours considérée comme le même prix de 1,23458.
Si vous aviez utilisé cette méthode, vous n'auriez pas eu ce problème :
*Il secoue sa cravate en position avec deux doigts* N'utilisez normalize double que dans les calculs impliquant une valeur double et pas seulement partout où il y a un double.
tonny: *N'utilisez NormalizeDouble que dans les calculs impliquant une valeur double et non pas partout où il y a un double.
Ou bien n'utilisez pas du tout NormalizeDouble(), la plupart du temps, lorsqu'il est utilisé, il n'est absolument pas nécessaire de l'utiliser... L'erreur 4107 peut être résolue en utilisant NormalizeDouble(), mais il existe d'autres moyens. Tout prix provenant de variables prédéfinies ou de fonctions de séries chronologiques n'aura jamais besoin d'être normalisé, pas plus que le résultat d'un nombre entier multiplié par Point.
Si vous n'avez pas de compte, veuillez vous inscrire
Autorisez l'utilisation de cookies pour vous connecter au site Web MQL5.com.
Veuillez activer les paramètres nécessaires dans votre navigateur, sinon vous ne pourrez pas vous connecter.
Vous êtes connecté. L'authentification à deux facteurs a été désactivée. Configurez-la à nouveau et scannez un nouveau code QR, ou continuez avec l'authentification à deux facteurs désactivée.
Si c'est pour la comparaison, vous pourriez facilement créer votre propre fonction :
C'est juste une idée.
Si c'est pour la comparaison, vous pourriez facilement créer votre propre fonction :
C'est juste une idée.
C'est une bonne idée, je vous en remercie :-)
L'utilisation de "Point" ou "Point/2.0" n'est pas une très bonne valeur de différence, IMO. L'erreur d'arrondi introduite par NormalizeDouble (qui m'a brûlé aujourd'hui), est certainement beaucoup plus petite que 8 chiffres, plus probablement 15 chiffres.
Compte tenu des conseils précédents, j'ai apporté quelques modifications et mis au point la routine suivante qui semble fonctionner correctement (même en utilisant la "différence" à 15 décimales), bien qu'elle n'ait pas encore été rigoureusement testée :
Here is a check of the obvious:
Voici encore une autre routine possible qui peut comparer, mais qui peut aussi normaliser en interne soit A et/ou B, et qui va aussi relaxer la différence de comparaison (de A-B ou B-A) à un nombre plus grand basé sur les "chiffres". Je doute que cette routine soit nécessaire par rapport à la simple "AvsB" ci-dessus, mais elle est proposée à votre usage si vous le souhaitez :
L'utilisation de "Point" ou "Point/2.0" n'est pas une très bonne valeur de différence, IMO. L'erreur d'arrondi introduite par NormalizeDouble (qui m'a brûlé aujourd'hui), est certainement beaucoup plus petite que 8 chiffres, plus probablement 15 chiffres.
Vous voulez la plus grande valeur qui ne peut pas être considérée comme une erreur d'arrondi ou, de manière équivalente, la plus petite valeur qui ne peut pas être considérée comme un changement de prix. Puisque les prix ne peuvent changer que d'un multiple de point, point/2 est exactement cela.
La valeur double du courtier pourrait être n'importe où entre 1,23457500000000 et 1,23458499999999999 et être toujours considérée comme le même prix de 1,23458.
Si vous aviez utilisé cette méthode, vous n'auriez pas eu ce problème :
if (a > b)if (a >= b)if (a != b)Devons-nous éviter d'utiliser la fonction normalisedouble ?
ou peut-être... j'ai pensé que nous pouvons utiliser lafonction MathRound
ex . double x= (MathRound( 1.37883 * 100000)) / 100000 ;
Ainsi, nous pouvons créer la fonction
*N'utilisez NormalizeDouble que dans les calculs impliquant une valeur double et non pas partout où il y a un double.
Devons-nous éviter d'utiliser la fonction normalisedouble ?
ou peut-être... j'ai pensé que nous pourrions utiliser la fonction MathRound
ex . double x= (MathRound( 1.37883 * 100000)) / 100000 ;
Vous vous retrouvez quand même avec un double et toujours la possibilité de prix != prix
Je suis arrivé à cette solution qui transforme les doubles en ints dans le but de comparer les doubles . . .
de sorte que...
ne sera jamais vrai.