Opérations et Expressions MQL4

 

Pour comprendre l’importance que les opérations et les expressions ont dans MQL4, des analogies ne sont pas nécessaires. Ce sont en fait les mêmes opérations que l’on retrouve en arithmétique. Tout le monde comprend que pour la séquence “f = n + m“, f, n et m sont des variables, les signes = et + sont des opérateurs, tandis que “n + m” est une expression.

Dans l’article précédant, nous avons appris les différents types de données. Maintenant nous allons nous intéresser aux relations existantes entre ces données (des mètres carrées ne peuvent pas être ajoutés à des pommes). En MQL4, il y a des limitations naturelles et des règles à propos de l’utilisation des opérations dans les expressions.

Les Notions d'”Opérandes”, de “Symbole d’Opérations” et d'”Expressions”

Une Opérande est une constante, une variable, un tableau ou une valeur retournée par une fonction (le terme de fonction et de tableau seront expliqués dans la section appropriée, à ce niveau de notre apprentissage il est suffisant de voire les opérandes comme les constantes ou variables que nous avons étudiées précédemment).

Une Opération est une action réalisée sur des opérandes.

Un symbole d’opération est un caractère réservé, ou un groupe de caractères réservés qui permettent d’exécuter une opération.

Une Expression est une séquence d’opérandes et de symboles d’opérations. C’est une partie du programme, la valeur calculée de ce qui est caractérisé par un type de données.

 

Les différents types d’opérations

En MQL4, les différents types d’opération sont:

  • les opérations arithmétiques;
  • les opérations d’assignement;
  • les opérations relationnelles;
  • les opérations Booléennes (logiques);
  • les opérations binaires;
  • les opérations virgules;
  • les opérations d’appel de fonction.

Les opérations sont utilisées dans les opérateurs. C’est seulement dans ces opérateurs que leur utilisation a un sens. La possibilité d’utiliser un opérateur est déterminée par ses propriétés. Si la propriété d’un opérateur vous autorise d’utiliser cette opération spécifique, alors vous pouvez le faire. Dans le cas contraire, vous ne devriez pas utiliser cette opération.

Opérations Arithmétiques

Les symboles suivants appartiennent aux opérations arithmétiques :

Symbole Opération Exemple Analogue
+ Addition de valeurs x + 2  
Soustraction de valeur ou changement de signe x – 3, y = – y  
* Multiplication de valeurs 3 * x  
/ Quotient d’une division x / 5  
% Reste d’une division minutes = time % 60  
++ Addition de 1 à la valeur de la variable y++ y = y + 1
Soustraction de 1 à la valeur de la variable y– y = y – 1

Opérations d’Assignement

Les symboles suivants appartiennent aux opérations d’assignement :

Symbole Opération Exemple Analogue
= Assignement de la valeur x à la variable y ? = x  
+= Augmentation de la variable y par x ? += x y = y + x
-= Réduction de la variable y par x y -= x y = y – x
*= Multiplication de la variable y par x y *= x y = y * x
/= Division de la variable y par x y /= x y = y / x
%= Reste de la division de la variable y par x y %= x y = y % x

Opérations Relationnelles

Les symboles suivants appartiennent aux opérations relationnelles :

Symbole Opération Exemple
== Vraie, si x est égal à y x == y
!= Vraie, si x n’est pas égal à y x != y
< Vraie, si x est inférieure à y x < y
> Vraie, si x est supérieur à y x > y
<= Vraie, si x est égal ou inférieur à y x <= y
>= Vraie, si x est égal ou supérieur à y x >= y

Opérations Booléennes (Logique)

Les symboles suivants appartiennent aux opérations booléennes :

Symbole Opération Exemple Explications
! NOT (négation logique) ! ? TRUE(1), si la valeur de l’opérande est FALSE(0); FALSE(0), si la valeur de l’opérande n’est pas FALSE(0).
|| OR (disjunction logique) x < 5 || x > 7 TRUE(1), si une des deux conditions est vraie
&& AND (conjonction logique) x == 3 && y < 5 TRUE(1), si toutes les conditions sont vraies

Opérations Binaires

Les opérations binaires ne peuvent être effectuées qu’avec des entiers. Les opérations suivantes appartiennent aux opérations binaires :

Le complément à la valeur de la variable. La valeur de l’expression contiens des 1 à la place des 0, et des 0 à la place des 1. Par exemple 0100 et 1011 sont de tels compléments.

b = ~n;

La représentation binaire de x est décalée de y places vers la droite. Ce décalage à droite est logique. Toutes les places libérées à gauche seront remplies de 0.

x = x >> y;

Cette fois ci la représentation binaire de x est décalée de y places vers la gauche. Toutes les places libérées à droite seront remplies de 0.

x = x << y;

L’opération binaire AND (&) de la représentation binaire de x et y. La valeur de l’expression obtenue contiens 1 (TRUE) à chaque place où les valeurs correspondantes de x et y sont aussi 1 (TRUE). En cas de deux 0 (FALSE) ou un 1 et un 0, le résultat est 0 (FALSE).

b = ((x & y) != 0)

L’opération binaire OR entre la représentation binaire de x et y. La valeur de l’expression obtenue contient des 1 aux places où x ou y ne contiennent pas de 0. Dans tous les autres cas on obtient des 0.

b = x | y;

L’opération binaire OR EXCLUSIF entre la représentation binianire de x et y. La valeur de l’expression obtenue contient des 1 aux places où x et y ont des valeurs binaires différentes. Dans les autres cas on obtient des 0.

b = x ^ y;

Opérations virgules

Les expressions séparées par des virgules sont traitées de la gauche vers la droite. Le type et la valeur du résultat coïncide avec le type et la valeur de l’expression de droite.

{xtypo_code}for(i=0,j=99; i<100; i++,j–) Print(array[i][j]); //Déclaration de boucle{/xtypo_code}

 

La liste des paramètres transférées (ci dessous) peut être considérée comme un exemple.

{xtypo_code}My_function (Alf, Bet, Gam, Del) // Appel d’une fonction avec des arguments.{/xtypo_code}

 

Les opérateurs, les fonctions et leurs appels sont considérés dans les chapitres suivants.

Opérations sur des Opérandes Similaires

Si l’on racontait à un élève d’école élémentaire que pour résoudre le problème du nombre de crayons il devrait utiliser des termes comme ceux d’opérandes, d’opérateurs et expressions, le pauvre enfant ne penserait pas qu’il en est capable. En regardant les symboles des différentes opérations, on pourrait penser que la programmation est très compliquée et donc réservée à une certaine élite. Cependant, coder n’est pas réellement difficile. Avec un minimum d’habitude, d’effort et d’exemples, tout ceci devrait apparaitre beaucoup plus claire.

{xtypo_info}Problème 1. John a deux stylos et Pierre a 3 stylos. Combien de stylos ont en tout les deux enfants? 🙂 {/xtypo_info}

 

Solution. Notons le nombre de stylos de John comme une variable nommée A et le nombre de stylos de Pierre une variable B. Le résultat est quand à lui une variable notée C. 

La réponse sera: C= ? + ?

Dans le chapitre précédent nommé Types de Données, nous avons étudié la manière de déclarer les variables. Les stylos sont des choses, c’est à dire quelque chose qui peut exister basiquement en tant que partie. Par exemple, il peut exister la moitié d’un stylo… Nous considèrerons donc les stylos comme des variables réelles de type double.

Nous pouvons donc par exemple coder la solution de la manière qui suit :

{xtypo_code}double A = 2.0; // Le nombre de stylos de John
double B = 3.0; // Le nombre de stylos de Pierre
double C = A + B; // Le nombre total{/xtypo_code}

 

Dans ce cas, l’opération “+” appliquée pour ajouter ensemble les valeurs des variables du même type est assez illustrative :

La valeur du type de l’expression “A+B” sera la type des variables qui la composent. Dans notre cas, le type sera donc double.

Nous obtiendrons un résultat similaire dans le cas où l’on fait la différence entre les valeurs (combien de stylo a de plus Pierre que John?) :

{xtypo_code}double A = 2.0; // Le nombre de stylos de John
double
B = 3.0; // Le nombre de stylos de Pierre
double C = BA; // La différence{/xtypo_code}

 

D’autres opérations arithmétiques peuvent être exécutées de la même manière.

{xtypo_code}double C = B * A; // Multiplication de deux nombres réels
double C = B / A; // Division de deux nombres réels{/xtypo_code}

 

Des calculs similaires peuvent être réalisés avec des entiers.

{xtypo_info}Problème 2. Les élèves vont au tableau pour répondre aux questions. John y est allé 2 fois tandis que Pierre 3 fois. Combien de fois les garçons y sont allés au total?{/xtypo_info}

 

Solution. Nous nous retrouvons dans un cas similaire du problème 1. Mais ici les passages ne peuvent être divisés en morceau. Nous devons donc utiliser des variables entières de type int au lieu des variables réelles. 

Reprenons les exemples de codes précédent en notant les variables comme étant des entiers.

{xtypo_code}int X = 2; // Nombre de passages de John
int Y = 3; // Nombre de passages de Pierre
int Z = X + Y; // Nombre total
int Z = YX; // Différence entre deux entiers
int Z = Y * X; // Produit de deux entiers
int Z = Y / X; // Quotient de deux entiers{/xtypo_code}

 

La situation est par contre un peu différente si on utilise des types string.

{xtypo_info}Problème 3. A l’angle d’une rue, il y a un magasin nommé “Arctique”. A un autre angle de la même rue, il y a un autre établissement appelé “Salon de Coiffure”. Qu’est il écrit sur les enseignes de la rue? {/xtypo_info}

 

Solution. En MQL4, vous êtes authorisé d’ajouter ensemble les valeurs des constantes et varibles de type string. Les strings sont simplement concaténées dans l’ordre où elles sont mentionnées dans l’expression :

Il est facile de coder un programme qui nous donnerait la réponse souhaitée :

{xtypo_code}string W1 = “Arctic”; // String 1
string W2 = “Hairdressing Saloon”; // String 2
string Ans = W1 + W2; // Concaténation des strings{/xtypo_code}

 

La valeur de la variable “Ans” sera la string qui apparaitra de cette manière :

{xtypo_code}ArcticHairdressing Saloon{/xtypo_code}

 

Ceci n’est pas très jolie à voire, mais c’est un vrai string. Bien sûr, nous devrions considérer les espaces et la ponctuation si nous réalisions un vrai programme.

N’importes quelle autre opération arithmétique avec des variables de type “string” sont interdites :

{xtypo_code}string Ans= W1 – W2; // Non autorisé
string Ans= W1 * W2; // Non autorisé
string Ans= W1 / W2; // Non autorisé{/xtypo_code}

Casting de Type

Le casting de type est la modification du type d’une opérande ou d’une expression. Avant l’exécution des opération (toutes sauf les opérations d’assignement), le type des opérandes ou expressions est changé pour celui d’une priorité supérieure, tandis qu’avant l’exécution de l’opération d’assignement, il ets changé pour le type cible.

Considérons quelques problèmes en relation avec le casting de type.

{xtypo_info}Problème 4. John a 2 crayons, tandis que Pierre est allé trois fois au tableau. Combien au total?{/xtypo_info}

Tant que la logique formelle est conservée, l’absurdité de ce problème est évident. Il est clair pour tout le monde que des évènements ne peuvent être ajoutés à des crayons.

{xtypo_info}Problème 5. A l’angle d’une rue, il y a un magasin nommé “Artique”, tandis qie John a 2 stylos. :){/xtypo_info}

 

Similairement, avec le même degré d’absurdité, nous pouvons demander:

1. Combien au total?, ou

2. Quel est l’enseigne du magasin?

Si vous désirez résoudre ces deux problèmes correctement en MLQ4, vous devez employer les règle de casting de type. Tout d’abord, nous devons parler des variables de différents types qui sont représentées dans la mémoire de l’ordinateur.

Les types de données comme les int, bool, color, datetime et double appartiennent aux types numériques. Leur représenttaion est un nombre. Les variables de type int, bool, color et datetime sont représentés en mémoire par des entiers, tandis que les variables de types bool par des nombres réels à virgule. Enfin, les valeurs des variables et constantes de type string sont des chaines de caractères (Fig. 16).

 


Fig. 16. Représentation de différents types de données dans la mémoire de l’ordinateur.

Nous avons mentionné au dessus que les valeurs des variables de types int, bool, color et datetime sont représentés dans le mémoire de l’ordinateur comme des entiers, tandis que le type double comme des réels. Donc si l’on veut choisir le type d’une expression constituée de variables de différents types, nous pouvons seulement choisir entre trois types de données: int, double et string. Les valeurs des types bool, color et datetime se comporteront dans une expression de la même manière que les valeurs de type int.

Alors, quel type sera la valeur d’une expression composée par des opérandes de différents types? En MQL4, la règle suivant impliquant le casting de type est acceptée :

{xtypo_alert}Règle 1: si l’expression contiens des opérandes de différents types, le type de l’expression sera transformé en type ayant la priorité la plus haute; les types int, bool, color et datetime ont des priorités égales, tandis que le type double a une plus grande priorité, et le type string a la priorité la plus haute.{/xtypo_alert}

 

{xtypo_alert}Règle 2: si le type de l’expression à droite du signe d’une opération d’assignement ne coïncide pas avec le type de la variable à la gauche de ce signe, la valeur de cette expression est “castée” au type de la variable de l’expression de gauche.{/xtypo_alert}

 

{xtypo_alert}Règle 3: il est interdit de “caster” les valeurs de type string en aucun des autres types.{/xtypo_alert}

 

Bon, revenons au problème 4. Il peut y avoir deux solutions.

Solution 4.1. Calcule du résultat de type int :

{xtypo_code}double A = 2.0; // Le nombre de stylos de John
int Y = 3; // Le nombre de passage de Pierre
int F = A + Y; // Nombre total{/xtypo_code}

 

Dans l’expression “A + Y”, les opérandes sont de deux types : A double et Y int.

En accord avec les règles de casting de type, la valeur de cette expression sera un nombre de type double. Notez bien que l’on est en train de parler de l’expression A+Y, et non à propos de l’expression F qui est à gauche du signe d’assignement. La valeur de cette expression est le nombre réel 5.0. Pour caster le type de l’expression, nous appliquons la première partie des règles. 

Après calcule de l’expression A+Y, l’opération d’assignement est réalisée. Dan s ce cas, les types ne sont pas non plus identiques. Le type de l’expression A+Y est double tandis que celui de F est int. Durant l’exécution de l’opération d’assignement, tout d’abord le type de l’expression A+Y est transformée en int (en accord avec la règle de calcul des entiers) et deviens l’entier 5. Ensuite ce résultat deviens la valeur entière de la variable F. Ceci respecte la deuxième règle que nous avons vue.

Solution 4.2. Une situation similaire arrive si nous essayons d’obtenir un résultat de type double :

{xtypo_code}double A = 2.0; // Le nombre de stylos de John
int Y = 3; // Le nombre de passages de Pierre
double F = A + Y; // Nombre total{/xtypo_code}

 

La situation diffère de la précédente par le fait que le type cible de la variable F est cette fois ci de type double, ce qui correspond au type de l’expression A+Y. Le résultat obtenu sera donc un nombre réel 5.0.

Cherchons maintenant une solution pour le Problème 5. Il n’y a pas de soucis lors de l’initialisation des variables.

{xtypo_code}string W1 = “Arctic”; // String 1
double A = 2; // Le nombre de stylos de John{/xtypo_code}

 

Solution 5.1. Une solution possible pour ce problème

{xtypo_code}string W1 = “Arctic”; // String 1
double A = 2; // Le nombre de stylos de John
string Sum = W1 + A; // Transformation à droite{/xtypo_code}

 

Ici, dans la partie de droite, nous ajoutons ensemble deux valeurs: une de type string et l’autre de type double. Selon la règle de casting, la valeur de la variable A sera transformée en type string qui a la plus haute priorité, et ensuite les deux valeurs seront concaténées.Le type de la valeur à droite du symbole d’assignement sera un string. A la prochaine étape, cette valeur sera assignée à la variable Sum de type string. La variable Sum correspondra donc à la chaine de caractère suivante:

{xtypo_code}Arctic2.00000000{/xtypo_code}

 

Solution 5.2. Cette solution est fausse:

{xtypo_code}string W1 = “Arctic”; // String 1
double A = 2; // Nombre de stylos de John
double Sum = W1 + A; // Inadmissible{/xtypo_code}

 

Dans ce cas, nous ne respectons pas une règle de casting numéro 3. L’expression W1+A est de type string et a donc la plus grande priorité, ce qui l’empêche d’être tansformé en type double. C’est une erreur qui sera détectée par le MetaEditeur lors de la compilation du programme.

Généralement, les règles de casting sont claires et simples. Si vous calculez un expression constituée de valeurs de différents types, vous devez “caster” ces types en un type de priorité plus élevé. Le casting avec des priorites plus faibles est authorisé seulement pour les valeurs numériques tandis que les chaines de caractères ne peuvent être transformées en nombres.

 

Caractéristiques de Calcule des Entiers

Les entiers sont connus comme les nombres n’ayant pas de parties fractionnelles. Si vous les ajoutez ensemble, ou vous les soustrayez, vous obtiendrez un résultat intuitif. Par exemple, si :

{xtypo_code}int X = 2; // Première variable int
int Y = 3; //Deuxième variable int{/xtypo_code}

 

et

{xtypo_code}int Z = X + Y; // Opération d’addition {/xtypo_code}

 

il n’y pas de problème à calculer la valeur de la variable Z: 2 + 3 = 5.

De manière identique, si vous exécutez l’opération de multiplication suivante :

{xtypo_code}int Z = X * Y; // Opération de multiplication{/xtypo_code}

 

le résultat est prévisible: 2 * 3 = 6

Mais quel est le résultat que l’on obtient dans le cas d’une division?

{xtypo_code}int Z = X / Y; // Division operation{/xtypo_code}

 

Il n’y a rien de compliqué à écrire  2 / 3. Cependant, ce n’est pas un entier. Quel sera donc la valeur de l’expression X/Y et de la variable Z?

{xtypo_alert}La règle de calcule des entiers spécifie que la patrie fractionnelle est toujours supprimée.{/xtypo_alert}

 

Dans l’exemple ci dessus, l’expression à la droite du signe d’égalité contiens seulement des entiers, c’est à dire qu’aucun casting de type n’a lieu dans ce cas. Et cela signifie que le type de l’expression X/Y est un int. Le résultat de l’expression  X/Y (= 2/3) est donc 0 (zéro). Cette valeur (zéro) sera assignée à la variable Z.

Evdemment, d’autres valeurs de X et de Y produiront des résultats différents :

{xtypo_code}int X = 7; // La valeur de la variable int
int Y = 3; // La valeur de la variable int
int Z = X / Y; // Opération de division{/xtypo_code}

 

Dans ce cas la valeur de l’expression X/Y (=7/3) et la variable Z seront égales à 2.

 

Ordre des Opérations

La règle de calcule est la suivante :

{xtypo_alert}La valeur d’une expression est calculée en fonction des priorités des opérations arithmétiques et de gauche à droite, chaqun des calculs intermédiaires respectant les règles du casting de type{/xtypo_alert}

 

Considérons le calcul de l’expression suivante :

{xtypo_code}Y = 2.0*( 3*X/ZN) + D; // Exemple d’expression{/xtypo_code}

 

L’expression à droite du signe d’égalité consiste de deux expressions que l’on somme:  2.0*( 3*X/Z – N) et D. L’expression 2.0*( 3*X/Z – N) est constituée de deux facteurs:  2 et (3*X/Z – N). L’expression en parenthèse  3*X/Z – N, est constituée à son tour de deux expressions: N et 3*X/Z constitué de trois facteurs: 3, X et Z.

Afin de calculer l’expression à droite du signe d’égalité, l’ordinateur calculera en premier l’expression de 3*X/Z. Cette expression contiens deux opérations (multiplication et division) du même rang, nous calculerons donc cette expression de gauche vers la droite. Premièrement nous calculerons la valeur de l’expression 3*X, le type de l’expression étant le même que celui de la variable X. Ensuite nous calculerons la valeur de l’expression 3*X/Z, son type étant calculé d’après les règles de casting. Après ça, le programme calculera la valeur et le type de l’expression  3*X/Z – N, puis de l’expression 2.0*( 3*X/Z – N), et pour finir l’expression entière 2.0*( 3*X/Z – N) + D.

Comme il est facile de s’en apercevoir, l’ordre de résolution des opérations est le même qu’en mathématique. Cependant, contrairement aux mathématique, l’ordre de calcul de ces résultats intermédaires peut avoir une grande importance sur le résultat final. Pour le démontrer, prenons un petit exemple.

{xtypo_warning}Calculez les valeurs des expressions ?/?*? et ?*?/? pour les entiers ?, ?, et ?. {/xtypo_warning}

 

Le résultat des calculs est intuitivement attendu comme identique pour les deux cas. Cependant, cette affirmation est faussevraie seulement pour des nombres réels. Si nous calculons les valeurs des expressions composés d’opérandes de type int, nous devrions toujours considérer le résultat intermédiaire. Dans un tel cas, la séquence des opérandes a une importance fondamentale :

{xtypo_code}int A = 3; // Valeur de type int
int B = 5; // Valeur de type int
int C = 6; // Valeur de type int
int Res_1 = A/B*C; // Résultat 0 (zero)
int Res_2 = A*C/B; // Résultat 3 (three){/xtypo_code}

 

Suivons le processus de calcul de l’expression A/B*C:

1. Premièrement (de gauche à droite) la valeur de l’expression A/B sera calculée. D’après les règles vue, la valeur de l’expression (3/5) est l’entier 0.

2. Calcul de l’expression 0*?.  Le résultat est l’entier 0.

3. Le résultat général (valeur de la variable Res_1) est l’entier 0.

 

Suivons maintenant le processus de calcul de l’expression A*C/B.

1. Calcul de A*C. La valeur de cette expression est l’entier 18 (3*6=18).

2. Calcul de l’expression 18/B. La réponse est évidente: après que la partie fractionelle ait été supprimée, (18/5) est l’entier 3.

3. Le résultat général (valeur de la variable Res_1) est l’entier 3.

 

Dans l’exemple ci-dessus, nous considérons juste un petit fragment de code pour lequel les valeurs des variables de type int sont calculées. Si nous plaçons ces variables avec des constantes de même valeur, le résultat final sera le même. Lorsque vous calculez des expressions contenant des entiers, vous devez faire attention au contenu de vos lignes de programmes. Sinon des erreurs pourraient survenir dans votre code, erreurs qui sont difficiles à identifier, notamment dans les grands programmes.  De tels problèmes n’apparaissent pas dans les calculs avec des nombres réels.

Dans les chapitres suivants, les termes et les propriétés générales des opérateurs seront approfondis. 

Retour sommaire.
Suivant: Opérateurs

Traduction: Nicolas Vitale
Source: http://book.mql4.com/basics/expressions
“MQL4 is a trade mark of MetaQuotes Software Corp. and all related materials are reserved for MetaQuotes”

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>