Erreurs, bugs, questions - page 107

 
Yedelkin:
Simplet, j'ai suivi le même chemin, mais j'ai utilisé une conversion explicite en type int. J'ai supposé que la taille maximale possible du lot sera limitée soit par le courtier ou le négociant, soit par la taille de mes propres fonds. Utiliser int devrait donc suffire. Pensez-vous qu'il y ait des pièges dans cette approche (arrondir à partir du bas en utilisant int) ?

Pour le commerce réel, probablement, oui, int/uint est suffisant.

Mais si vous l'exécutez dans un testeur, cela peut ne pas être suffisant pour certaines expériences.

Il n'y a pas d'écueils, à part d'éventuels problèmes dans l'implémentation de MQL5, lorsque l'on utilise int, si l'on peut garantir que le nombre entier N de la formule sera compris dans la plage 0...INT_MAX et donc que l'on ne débordera pas. C'est-à-dire, remplacer le contrôle

tmp < ULONG_MAX * stepvol

à

tmp < INT_MAX * stepvol

En fait, le type int est signé et la moitié de ses valeurs possibles se situent dans la zone des nombres négatifs, alors qu'ici elles seront toujours non négatives. Il est irrationnel d'utiliser int lorsqu'il existe un uint non signé qui a la même taille mais deux fois la portée dans la zone non négative. Par conséquent, si nous devons utiliser int/uint, il est préférable d'utiliser uint et de remplacer le contrôle par uint, respectivement :

tmp < UINT_MAX * stepvol
 

gumgum:

#property script_show_inputs

Merci pour le conseil.
 
simpleton:

Pour le commerce réel, très probablement oui, int/uint est suffisant.

...En fait, le type int est signé, la moitié de ses valeurs possibles se situent dans la zone des nombres négatifs, et ici il sera toujours non négatif. Il est irrationnel d'utiliser int, alors qu'il existe un uint non signé qui a la même taille mais deux fois la plage dans la zone non négative. Par conséquent, si nous devons utiliser int/uint, il est préférable d'utiliser uint et de remplacer le contrôle par uint, respectivement :

Oui, je l'ai, merci !
 

Il ne s'agit pas d'un bogue, mais d'une observation intéressante sur les types de produits.

D'après vous, que représente 2 fois 2, c'est-à-dire 2*2 ?

vous pensez que 4 peut-être vous avez raison !

OK, que dites-vous de ça
deux cent mille fois deux cent mille

200000 * 200000

N'importe quel écolier peut multiplier deux et quatre, ajouter des zéros et obtenir...

40000000000.

Maintenant, écrivons un code simple dans le langage de la machine.

lots longs = 200000*200000 ;

Notez que le type d'hôte de la variable est long, à savoir
La valeur minimale est -9 223 372 036 854 775 808 ; la valeur maximale est 9 223 372 036 854 775 807.

Imprimez le total et vous obtenez

lots = 1345294336
c'est loin d'être deux fois deux et vous en aurez deux.

J'ai relu la section d'aide sur les types et les conversions de types.
Je n'ai pas trouvé d'information indiquant que les nombres réguliers doivent être explicitement coulés dans le bon type.

c'est donc comme ça que ça devrait être

long lots = (long) 200000 * (long) 200000 ;

Vous pouvez également utiliser des variables auxiliaires supplémentaires.

Документация по MQL5: Основы языка / Типы данных / Приведение типов
Документация по MQL5: Основы языка / Типы данных / Приведение типов
  • www.mql5.com
Основы языка / Типы данных / Приведение типов - Документация по MQL5
 

Il y a plus.

Si vous voulez récupérer et multiplier par de grands nombres certaines propriétés....

Voici le code

long A = AccountInfoInteger(ACCOUNT_LOGIN);  // 661701
long B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
long X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);

Et voici le résultat

L1=2322042704   L2=2322042704   L3=6617010000
A =661701        B =661701      C =661701
les entrées sont les mêmes, mais le résultat est différent
Dossiers :
servis.mq5  2 kb
 

SHOOTER777:

Et maintenant un code simple en langage machine

lots longs = 200000*200000 ;

Notez que le type de réception d'une variable longue est long, c'est à dire
La valeur minimale est -9 223 372 036 854 775 808, la valeur maximale est 9 223 372 036 854 775 807.

Imprimez le total et obtenez

lots = 1345294336
c'est loin d'être deux fois deux et vous en aurez deux.

J'ai relu la section d'aide sur les types et les conversions de types.
Je n'ai pas trouvé d'information indiquant que vous devez explicitement attribuer un certain type aux nombres réguliers.

c'est donc comme ça que ça devrait être

long lots = (long) 200000 * (long) 200000 ;

Vous pouvez également utiliser des variables auxiliaires.

Les "nombres ordinaires" sont des expressions constantes qui ont également un type. Dans ce cas, il s'agit du type int.

L'expression consistant en la multiplication de deux sous-expressions, chacune d'entre elles étant de type int, est également de type int. C'est là que le débordement se produit.

Et ce n'est qu'à ce moment-là que la conversion implicite du type de l'expression int en type long se produit pendant l'initialisation de la variable de type long.

Tout est clair ici. D'ailleurs, chacun des opérandes dans ce cas n'a pas besoin d'être converti en type long. Il suffit d'en lancer un, et le second sera lancé implicitement.

 
SHOOTER777:

Il y a plus.

Si vous voulez récupérer et multiplier par de grands nombres certaines propriétés....

Voici le code

Et voici le résultat.

Les données sources sont les mêmes, mais le résultat est différent.

On dirait que le journal et le code sont mélangés. Le code ci-dessus fonctionne "proprement". Et, pour obtenir un tel journal, je devais faire en sorte que les variables A et B soient de type int ou uint, et la variable X de type uint:

void OnStart()
{
int A = 661701;
int B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
uint X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);
}

/* Вывод в лог (хронология - сверху вниз):
KO      0       1 (EURUSD,M15)  00:46:28         A=661701  B=661701  C=661701
OE      0       1 (EURUSD,M15)  00:46:28         L1=2322042704   L2=2322042704   L3=6617010000
*/

Et voici comment fonctionne le code original :

void OnStart()
{
long A = 661701;
long B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
long X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);
}

/* Вывод в лог (хронология сверху вниз):
DL      0       1 (EURUSD,M15)  00:49:13         A=661701  B=661701  C=661701
HG      0       1 (EURUSD,M15)  00:49:13         L1=6617010000   L2=6617010000   L3=6617010000
*/

Build 314 (20 août 2010).

Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Типы char, short, int и long - Документация по MQL5
 

Pouvez-vous me dire, par exemple, si je veux obtenir la valeur d'un indicateur. J'avais l'habitude de l'obtenir de manière précise et garantie en utilisant la fonction intégrée. Maintenant, je dois l'écrire moi-même en utilisant un tas de code, de tampons, de poignées, etc. Mais ce n'est pas la question. Le principal problème pour moi est que le code devient glitchy littéralement sur chaque ligne, parce que je dois vérifier chaque ligne de code pour m'assurer qu'aucune erreur ne s'est produite... En général, je pensais que toutes ces complexités, classes et choses élémentaires mais devenues encombrantes et peu pratiques étaient faites pour augmenter la vitesse, la fiabilité, etc... J'ai lu un article sur les 20 signaux... il est dit :

"Vous ne pouvez pas accéder aux données de l'indicateur juste après sa création, car il faut un certain temps pour calculer les valeurs de l'indicateur, il est donc préférable de créer les poignées de l'indicateur dans OnInit()".

Ensuite, il y a des contrôles pour chaque ligne

"Vérifions-les : s'il y a moins de données que ce dont nous avons besoin, cela signifie qu'une erreur de copie s'est produite et que tout nouvel accès au tableau, où les données devraient être stockées, entraînera une erreur. Pour exclure cette possibilité, nous allons quitter la fonction."

Donc, au lieu d'accélérer, je dois faire une boucle (combien de fois ?) à travers cette fonction pour obtenir un résultat à la fin... Et si j'ai besoin de valeurs individuelles de lignes distinctes de différents indicateurs de façon périodique... Il s'agit d'une fonction distincte pour chaque valeur... C'est beaucoup de variables et de code supplémentaires...

Bref, expliquez-moi, donnez moi un lien, je veux comprendre le sens de tout cela, pourquoi c'est si et moins fiable....

Et il serait bon que les réponses à de telles questions puissent être placées dans la section d'aide à la migration de µl4 vers µl5 ou de créer une section pertinente sur le forum, sans aucune discussion, spécifiquement une question et une réponse, avec une explication du pourquoi... par exemple, la période est expliquée ici de manière très accessible, et de la même manière nous aimerions avoir des réponses aux questions élémentaires

 
Dmitriy2:

Pouvez-vous me dire, par exemple, si je veux obtenir la valeur d'un indicateur. J'avais l'habitude de l'obtenir exactement et sûrement en utilisant la fonction intégrée. Maintenant, je dois l'écrire moi-même en utilisant un tas de code, de tampons, de poignées, etc. Mais ce n'est pas la question. Le principal problème pour moi est que le code devient glitchy littéralement sur chaque ligne, parce que je dois vérifier chaque ligne de code pour m'assurer qu'aucune erreur ne s'est produite... En général, je pensais que toutes ces complexités, classes et choses élémentaires mais devenues encombrantes et peu pratiques étaient faites pour augmenter la vitesse, la fiabilité, etc... J'ai lu un article sur les 20 signaux... il est dit :

"Vous ne pouvez pas accéder aux données de l'indicateur juste après sa création, car il faut un certain temps pour calculer les valeurs de l'indicateur, il est donc préférable de créer les poignées de l'indicateur dans OnInit()".

Ensuite, il y a des contrôles pour chaque ligne

"Vérifions-les : s'il y a moins de données que ce dont nous avons besoin, cela signifie qu'une erreur de copie s'est produite et que tout nouvel accès au tableau, où les données devraient être stockées, entraînera une erreur. Pour exclure cette possibilité, nous allons quitter la fonction."

Donc, au lieu d'accélérer, je dois faire une boucle (combien de fois ?) à travers cette fonction pour obtenir un résultat à la fin... Et si j'ai besoin de valeurs individuelles de lignes distinctes de différents indicateurs de façon périodique... Il s'agit d'une fonction distincte pour chaque valeur... C'est beaucoup de variables et de code supplémentaires...

Bref, expliquez-moi, donnez moi un lien, je veux comprendre le sens de tout cela, pourquoi c'est si et moins fiable....

Et il serait bon que les réponses à de telles questions puissent être placées dans la section d'aide à la migration de µl4 vers µl5 ou de créer une section pertinente sur le forum, sans aucune discussion, spécifiquement une question et une réponse, avec une explication du pourquoi... par exemple, la période est expliquée ici de manière très accessible, il serait bon d'avoir des réponses aux questions élémentaires de la même manière

Est-il plus fiable ? Pourquoi n'est-il pas fiable d'obtenir des poignées à l'initialisation ? Pourquoi n'est-il pas fiable de vérifier la disponibilité des données requises ? Et d'ailleurs, pourquoi n'est-il pas fiable de mettre en place des contrôles ?

Ce n'est peut-être pas si facile pour les débutants, mais avec le temps, cela deviendra clair...

 
Interesting:

Plus fiable ? Pourquoi l'obtention de handles à l'initialisation n'est-elle pas fiable ? Pourquoi n'est-il pas fiable de vérifier les données nécessaires ? Et plus encore, pourquoi le fait d'avoir des contrôles n'est-il pas fiable ?

Ce n'est peut-être pas si simple pour les débutants, mais cela deviendra clair avec le temps...

La vérification des données ne dégrade pas la vitesse du programme dans son ensemble, peut-être seulement de 0,01%, je n'ai pas fait cette vérification, et le fait que les données doivent être vérifiées avant de les utiliser est juste pour la stabilité de l'ensemble du système, sinon il peut y avoir des conséquences imprévisibles, jusqu'au crash du terminal dans son ensemble.
Raison: