Operations and Expressions
In order to understand what importance operations and expressions have in MQL4, no special analogies are needed. Practically, it is the same as operations and expressions in simple arithmetic. Everybody understands that in the record of f = n + m, members f, n and m are variables, signs = and + are operational signs, whereas n + m is an expression.
In the preceding section of the book, we learned about the necessity to present data of different types. Here we will get into possible relationships between these data (square meters still cannot be added to apples). In MQL4, there are some natural limitations and the rules of using operations in expressions.
The Notions of 'Operand', 'Operation', 'Operation Symbol' and 'Expression'
Operand is a constant, a variable, an array component or a value returned by a function (the term of function is considered in the section of Functions, that of array - in the section of Arrays; at this present stage of learning, it is sufficient to understand operands as constants and variables we have already studied before).
Operation is an action made upon operands.
Operation symbol is a preset character or a group of characters that order to execute an operation.
Expression is a sequence of operands and operation symbols; it is a program record, the calculated value of which is characterized by a data type.
Types of Operations
There are the following types of operations in MQL4:
- arithmetical operations;
- assignment operations;
- relational operations;
- Boolean (logical) operations;
- bitwise operations;
- comma operation;
- function call.
Operations are used in operators (see Operators). Only in operators their use makes sense and is realized in a program.
The possibility to use an operation is determined by the properties of operators (if the operator's properties allow you to utilize this specific operation, you can use it; otherwise, you shouldn't utilize this operation).
It is prohibited to use operations outside operators.
Arithmetical Operations
The following symbols belong to arithmetical operations symbols:
| Symbol |
Operation |
Example |
Analog |
| + |
Addition of values |
x + 2 |
|
| - |
Subtraction of values or sign change |
x - 3, y = - y |
|
| * |
Multiplication of values |
3 * x |
|
/
|
Quotient of division |
x / 5 |
|
| % |
Residue of division |
minutes = time % 60 |
|
| ++ |
Addition of 1 to the value of the variable |
y++ |
y = y + 1 |
| -- |
Subtraction of 1 from the value of the variable |
y-- |
y = y - 1 |
Assignment Operations
The following symbols belong to assignment operations symbols:
Symbol
|
Operation |
Example |
Analog |
| = |
Assignment of the value x to the variable y |
у = x |
|
| += |
Increase of the variable y by x |
у += x |
y = y + x |
| -= |
Reduction of the variable y by x |
y -= x |
y = y - x |
| *= |
Multiplication of the variable y by x |
y *= x |
y = y * x |
| /= |
Division of the variable y by x |
y /= x |
y = y / x |
| %= |
Residue of division of the variable y by x |
y %= x |
y = y % x |
Relational Operations
The following symbols belong to relational operations symbols:
| Symbol |
Operation |
Example |
| == |
True, if x is equal to y |
x == y |
| != |
True, if x is not equal to y |
x != y |
| < |
True, if x is less than y |
x < y |
| > |
True, if x is more than y |
x > y |
| <= |
True, if x is equal to or less than y |
x <= y |
| >= |
True, if x is equal to or more than y |
x >= y |
Boolean (Logical) Operations
The following symbols belong to Boolean operations symbols:
| Symbol |
Operation |
Example |
Explanations |
| ! |
NOT (logical negation) |
! х |
TRUE(1), if the value of the operand is FALSE(0); FALSE(0), if the value of the operand is not FALSE(0). |
| || |
OR (logical disjunction) |
x < 5 || x > 7 |
TRUE(1), if any value of the values is true |
| && |
AND (logical conjunction) |
x == 3 && y < 5 |
TRUE(1), if all values are true |
Bitwise Operations
Bitwise operations can only be performed with integers. The following operations belong to bitwise operations:
One's complement of the value of the variable. The value of the expression contains 1 in all places, in which the values of the variable contain 0,
and it contains 0 in all places, in which the values of the variable contain 1.
The binary representation of x is shifted by y places to the right. This right shift is logical, it means that all places emptied to the left will be filled with zeros.
The binary representation of x is shifted by y places to the left; the emptied places to the left will be filled with zeros.
The bitwise operation AND of the binary representations of x and y. The value of the expression contains 1 (TRUE) in all places, in which both x and y contain non-zero; and the value of the expression contains 0 (FALSE) in all other places.
The bitwise operation OR of the binary representations of x and y. The value of the expression contains 1 in all places, in which x or y does not contain 0. It contains 0 in all other places.
The bitwise operation EXCLUSIVE OR of the binary representations of x and y. The value of the expression contains 1 in the places, in which x and y have different binary values. It contains 0 in all other places.
Comma Operation
Expressions separated by commas are calculated left to right. All side effects of calculations in the left expression can only occur before the right expression is calculated. The type and value of the result coincide with the type and value of the right expression.
| for(i=0,j=99; i<100; i++,j--) Print(array[i][j]); // Loop statement |
The transferred parameter list (see below) can be considered as an example.
| My_function (Alf, Bet, Gam, Del) // Calling for a function with arguments |
Operators and functions are considered in the sections of Operators, Functions and in the chapter named Operators)
Function Call
Function call is described in all details in the section of Function Call.
Operations on Similar Operands
If an elementary school pupil were told that, when solving the problem about the number of pencils, he or she would have to base his or her presentation on such terms as operands, operators and expressions, the poor schoolchild would surely find it impossible. Looking at the symbols of operations, one may think that coding is a mysterious and very complicated process, accessible only for for a kind of elite. However, coding isn't really difficult at all, you just need to make head or tail of some intensions. To be sure that this is really so, let's consider some examples.
 |
Problem 1. John has 2 pencils, Pete has 3 pencils. How many pencils do these boys have?:) |
Solution. Let us denote the number of John's pencils as variable A and the number of Pete's pencils as variable B, whereas the result will be denoted as C.
The answer will be: С = А + В
In the section named Data Types, we considered the methods of variable declaration. Pencils are things, i.e., it is something that can basically exist as a part (for example, there can be a half of a pencil). Thus, we will consider pencils as real variables, i.e., the variables of double type.
So we can code the solution, for example, as follows:
double A = 2.0;
double B = 3.0;
double C = A + B;
In this case, operation "+" applied to adding together the values of the one-type variables is quite illustrative.
The value type of the expression:
A + B
will be the type of the variables that are components of the expression. In our case, this will be the double type.
We will get the similar answer for the difference between the values (How many more pencils does Pete have than John?):
double A = 2.0;
double B = 3.0;
double C = B - A;
Other arithmetical operations are used in a similar manner:
double C = B * A;
double C = B / A;
Similar calculations can be performed with integers, too.
 |
Problem
2. Pupils go to the blackboard and answer in class. John went 2 times, Pete went 3 times. How many times did boys go to the blackboard in total? |
Solution. Let us denote John's passages as variable X, Pete's passages as variable Y, the result - as Z.
In this example, we have to use the variables of int type,
since we consider events that are integer by their nature (you cannot go to the blackboard 0.5 times or 1.5 times; the answer at the blackboard can be good or poor, but we're only interested in the number of such answers or passages).
The solution of this problem can be written as:
int X = 2;
int Y = 3;
int Z = X + Y;
In case of calculation of the difference between, product of or quotient of integers, the operation "-" is used in the similar simple manner:
int X = 2;
int Y = 3;
int Z = Y - X;
int Z = Y * X;
int Z = Y / X;
The situation is a bit different with the variables of string type:
 |
Problem
3. At one corner of the house, there is a grocery store named "Arctic". At another corner of the same house, there is an establishment named "Hairdressing Saloon".
What is written on the house? |
Solution. In MQL4, you are allowed to add together the values of string constants and variables. If we add together variables of string type, strings are simply added one by one, in the sequence they are mentioned in the expression.
It is easy to code a program that would give us the necessary answer:
string W1 = "Arctic";
string W2 = "Hairdressing Saloon";
string Ans = W1 + W2;
The value of variable Ans will be the string that appears as follows:
| ArcticHairdressing Saloon |
We obtained a not-much-to-look-at, but absolutely correctly formed value of string type. Of course, we should consider gaps and other punctuation in our practical coding of such problems.
Any other arithmetical operations with variables of string type are prohibited:
string Ans= W1 - W2; // Not allowed
string Ans= W1 * W2; // Not allowed
string Ans= W1 / W2; // Not allowed
Typecasting
Typecasting is modifying (mapping) of types of the values of an operand or an expression. Before execution of operations
(all but assignment operations), they are modified to a type of the
highest priority, whereas before execution of assignment operations
they are modified to the target type.
Let's consider some problems that deal with typecasting.
 |
Problem 4. John has 2 pencils, whereas Pete went 3 times to the blackboard. How many in total? |
As far as the formal logic is concerned, the ill-posedness of the problem is obvious. It stands to reason that events cannot be added together with things, it is wrong.
 |
Problem 5. At one corner of the house, there is a grocery store named "Arctic", whereas John has 2 pencils.:) |
With the same degree of hopelessness (as far as normal reasoning is concerned) we can ask either:
1. How many in total?, or
2. What is written on the house?
If you want to solve both problems above correctly in MQL4,
you should refer to typecasting rules. First, we have to talk about how variables of different types are represented in the computer memory.
Data types, such as int, bool, color, datetime and double, belong to the numeric data type. The internal representation of constants and variables of int, double, bool, color and datetime type is a number.
The variables of int, bool, color and datetime types are represented in the computer memory as integers, whereas the variables of double type are represented as double-precision numbers with a floating point, i.e., real numbers.
The value of constants and variables of string type is a set of characters (Fig. 16).
 |
The values of int, bool, color and datetime types are represented in the computer memory as integers. The values of double type are represented in the computer memory as real numbers. The values of string type are represented in the computer memory
as a sequence of characters. The values of int, bool, color,
datetime and double types are the values of numeric type. The values of string type are the values of character type. |

Fig. 16. Representation of different data types in the computer memory.
We mentioned above that the values of the variables of int, bool, color and
datetime types are represented in the computer memory as integers, whereas those of double type - as real numbers. So, if we want to find out about the type of an expression that consists of variables of different types, we can only choose between three data types: int, double and string. The values of
bool, color and datetime types will prove themselves in an expression in the same way as
the values of int type.
So, what type will be the value of an expression composed of operands of different types? In MQL4, the rule of implied typecasting is accepted:
 |
- if the expression contains operands of different types, the expression type will be transformed into the type having the highest priority; the types int,
bool, color and datetime have equal priorities, whereas the double type has a higher priority, and the string type has the highest priority;
- if the type of the expression to the right of the assignment operation sign does not coincide with the type of the variable to the left of the assignment operation sign, the value of this expression is cast as the type of the variable to the left of the assignment operation sign; this is called 'target-type cast';
- it is prohibited to cast the values of string type to any other target type.
|
Well, let's return to Problem 4. There can be two solutions for it.
Solution 4.1. Calculation of the result of int type:
double A = 2.0;
int Y = 3;
int F = A + Y;
First of all, we need to know the value of the expression provided its operands are of different types. In the expression:
A + Y,
operands of two data types are used: А -
double type, Y -
int type.
In compliance with the rule of implied typecasting, the value of this expression will be a number of double type. Please note: We are talking only about the type of expression A+Y, but not about the type of variable F that is to the left of the assignment operation sign. The value of this expression is real number 5.0. To cast the type of expression A+Y, we applied the first part of the implied typecasting rule.
After calculation of the expression A+Y, the assignment operation is executed. In this case, the types mismatch, too: the type of expression A+Y is
double, whereas the type of variable
F is int. During execution of the assignment operation: First, the type of expression A+Y is casted as int (according to the rule of integer calculations)
and becomes integer 5; then this result becomes the value of the integer variable F. The calculations have been performed according to the second part of the implied typecasting rule - 'target-type cast'. The final result of calculations and manipulations is as follows: The value of the integer variable F is integer
5.
Solution 4.2. A similar situation occurs, if we try to have a result as a value of double type:
double A = 2.0;
int Y = 3;
double F = A + Y;
This situation differs from the preceding one by that the target type of variable F (to the left of the assignment operation sign), in our case, it is double type, coincides with the type (double) of the expression A+Y, so we don't have any target-type cast here. The result of calculations (the value of the double-type variable F) is real number 5.0.
Let's now find a solution for Problem 5. No questions come up at initialization of variables:
string W1 = "Arctic";
double A = 2;
Solution 5.1. A possible solution for this problem:
string W1 = "Arctic";
double A = 2;
string Sum = W1 + A;
Here, in the right part, we add together the values of two variables: the one of string type, and the other one - of double type. According to the rule of implied typecasting, the value of variable A will first be cast to the string type (since this type is of a higher priority), and then the one-type values will be added together (concatenation).
The type of the resulting value to the right of the assignment operation sign will be string. At the next stage, this value will be assigned to the string variable Sum. As a result, the value of variable Sum will be the following string:
Solution 5.2. This solution is wrong:
string W1 = "Arctic"; // String 1
double A = 2; // Number of John's pencils
double Sum = W1 + A; // This is inadmissible
In this case, we break a prohibition of target-type cast for the values of string type. The type of the value of expression W1+A, like in the preceding solution,
is string. When the assignment operation is executed, the target-type cast must be performed. However, according to the rule, the string-type target cast to the types of lower priority is prohibited. This is an error that will be detected by MetaEditor at creation of the program (at compilation).
Generally, the rules given in this section are clear and simple: If you calculate any values, you must cast all differing types to a type with the highest priority.
Typecasting with lowered priority is allowed only for numeric values, whereas strings cannot be transformed into numbers.
Features of Integer Calculations
Integers are known to be the numbers without a fractional part.
If you add them together or subtract them, you will get an intuitive result.
For example, if:
int X = 2;
int Y = 3;
and:
int Z = X + Y;
there is no problem to calculate the value of variable Z: 2 + 3 = 5
Similarly, if you execute a multiplication operation:
int Z = X * Y;
the result is highly predictable: 2 * 3 = 6
But what result do we get, if our program has to execute a division operation?
int Z = X / Y;
It's easy to write 2 / 3. However, it is not an integer. So, what will be the value of expression X/Y and variable Z?
 |
The rule of integer calculations consists in that the fractional part is always discarded.
|
In the above example, the expression to the right of the equality sign contains only integers, i.e., no typecasting takes place, in this case. And this means that
the type of expression X/Y is int. So the result of finding the integer value of expression X/Y (= 2/3) is 0 (zero). This value (zero) will be assigned to variable Z at the end.
Correspondingly, other values of variables X and Y will produce other results. For example, if:
int X = 7;
int Y = 3;
int Z = X / Y;
then the value of 7 / 3 for the expression X / Y and variable Z is equal to 2 (two).
Order of Operations
The calculating rule consists in the following:
 |
The value of an expression is calculated according to the priorities of arithmetical operations and left to right, each intermediate outcome being calculated according to the typecasting rules. |
Let's consider the calculating order for an expression in the following example:
Y = 2.0*( 3*X/Z - N) + D;
The expression to the right of the equality sign consists of two summands:
2.0*( 3*X/Z - N) and D. The summand 2.0*( 3*X/Z - N) consists of two factors, namely: 2 and (3*X/Z - N). The expression in parentheses, 3*X/Z - N, in its turn, consists of two summands, the summand 3*X/Z consisting of three factors, namely: 3, X and Z.
In order to calculate the expression to the right from the equality sign, we will, first, calculate the value of expression 3*X/Z. This expression contains two operations (multiplication and division) of the same rank, so we will calculate this expression left to right. First, we will calculate the value of expression 3*X, the type of this expression being the same as the type of the variable X. Then we will calculate the value of expression 3*X/Z, its type being calculated according to the typecasting rule. After that, the program will calculate the value and the type of the expression 3*X/Z - N, then - of the expression 2.0*( 3*X/Z - N), and the last - of the entire expression 2.0*( 3*X/Z - N) +
D.
As is easy to see, the order of operations in a program is similar to that in mathematics. However, the former one differs in calculating of the types of values in intermediate outcomes, which exercises a significant influence on the final result of calculations. Particularly (unlike the rules accepted in mathematics), the order of operands in an expression is very important. To demonstrate this, let's consider a small example.
 |
Problem 6.Calculate the values of expressions А/В*С and А*С/В for integers А, В, and С.
|
The result of calculation is intuitively expected to be the same, in both cases. However, this statement is true only for
real numbers. If we calculate the values of expressions composed of the operands of int type,
we should always consider the intermediate outcome. In such a case, the sequence of operands is of fundamental importance:
int A = 3;
int B = 5;
int C = 6;
int Res_1 = A/B*C;
int Res_2 = A*C/B;
Let's follow the process of calculating the expression A/B*C:
1. First (from left to right) the value of the expression A/B will be calculated. According to the above rules, the value of the expression (3/5)
is integer 0 (zero).
2. Calculation of the expression 0*С (zero multiplied by С). The result is integer 0 (zero).
3. General result (the value of the variable Res_1) is integer 0 (zero).
Let's now follow the developments of calculating the expression A*C/B.
1. Calculation of A*C. The value of this expression is integer 18 (3*6=18).
2. Calculation of the expression 18/B. The answer is obvious: after the fractional part has been discarded, (18/5) is integer 3 (three).
3. General result (the value of variable Res_2) is integer 3 (three).
In the above example, we consider just a small code fragment, in which the values of the variables of int type are calculated. If we replace these variables with constants with the same values, the final result will be the same. When calculating expressions containing integers, you must pay greater attention to the contents of your program lines. Otherwise, an error may occur in your code, which would be very difficult to find and fix later (especially in large programs). Such troubles do not occur in calculations using real numbers.
However, if you use operands of different types in one complex expression, the final result may fully depend on a randomly formed fragment containing division of integers.
In the section of Operators, the term and general properties of operators are considered, whereas the special properties of each operator are described in the chapter named Operators.