MQL4 Book  Basics of MQL4  Operations and Expressions

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 f = n + m, members f, n, and m are variables, signs = and + are operational signs, and n + m is an expression.

In the preceding section of the book, you 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 to 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. (Functions are considered in the section on functions; arrays is considered in the section on arrays; at this present stage of learning, it is sufficient to understand operands as constants, and variables we have already studied.)

An operation is an action made upon operands.

An operation symbol is a preset character or group of characters that order to execute an operation.

An 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

These are the following types of operations in MQL4:

Arithmetical

Assignment

Relational

Boolean

Bitwise

Comma

Function call

Operations are used in operators (see Operators). Only in operators does 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 should not use this operation. It is prohibited to use operations outside operators.

Arithmetical operations

The following symbols are arithmetical operation 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 are assignment operation 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 are relational operation 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 are Boolean operation 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 are bitwise operations.

This returns the one's complement of the value of the variable. The value of the expression contains a 1 in all places in which the values of the variable contain a 0, and it contains a 0 in all places in which the values of the variable contain a 1.

b = ~n;

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.

x = x >> y;

The binary representation of x is shifted by y places to the left; the emptied places to the left will be filled with zeros.

x = x << y;

The following example demonstrates 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.

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

The following example demonstrates 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.

b = x | y;

The following example demonstrates 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.

b = x ^ y;

Comma operation

Expressions separated by commas are calculated left to right. All effects of calculations in the left expression 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 following transferred parameter list can be considered as an example.

My_function (Alf, Bet, Gam, Del) // Calling for a function with arguments

For more information on operators and functions, see the operators and functions sections within this chapter. For more in-depth detail, see the operators chapter.

Function call

Function call is described in detail in the function call section.

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 child would surely find it impossible. Looking at the symbols of operations, you may think that coding is a mysterious and very complicated process, accessible only to a kind of elite. However, coding is not really difficult at all, you just need to clarify some intentions. To be sure that this is really so, let us consider some examples.

icon_question

Problem 1 John has two pencils, Pete has three pencils. How many pencils do these boys have? :)

Solution 1 Let us denote the number of John's pencils as variable A and the number of Pete's pencils as variable B, whereas the total will be denoted as C.

The answer is С = А + В.

In the data types section, we considered the methods of variable declaration. Pencils are things, that is 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, that is the variables of double type.

So, we can code the solution, for example, as follows.

double A = 2.0;                       // The number of John's pencils
double B = 3.0;                       // The number of Pete's pencils
double C = A + B;                     // Total number

In this case, it is quite illustrative to consider the operation "+" applied to adding together variables of the same data type.

The value type of the following expression will be the type of the variables that are components of the expression. In our case, this will be the double type.

A + B

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;                       // The number of John's pencils
double B = 3.0;                       // The number of Pete's pencils

Other arithmetical operations are used in a similar manner.

double C = B * A;                     // Multiplication of two real numbers
double C = B / A;                     // Division of two real numbers
Similar calculations can be performed with integers, too.

icon_question

Problem 2 Pupils go to the blackboard and answer in class. John went two times, and Pete went three times. How many times did boys go to the blackboard in total?

Solution 2 Let us denote John's passages as variable X, Pete's passages as variable Y, and 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. For example, 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 are only interested in the number of such answers or passages.

The solution of this problem can be written in the following way.

int X = 2;                           // Number of John's passages
int Y = 3;                           // Number of Pete's passages
int Z = X + Y;                       // Total number

In the cases of the calculation of the difference between integers, product of integers, or quotient of integers, the appropriate operations are used in the same simple manner.

int X = 2;                           // Integer
int Y = 3;                           // Integer
int Z = Y - X;                       // Difference between two integers
int Z = Y * X;                       // Product of two integers
int Z = Y / X;                       // Quotient of two integers
The situation is a bit different with variables of string type.

icon_question

Problem 3 At one corner of a building, there is a grocery store named "Arctic." At another corner of the same building, there is an establishment named "Hairdressing Saloon." What is written on the building?

Solution 3 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 1
string W2  = "Hairdressing Saloon";          // String 2
string Ans = W1 + W2;                        // Sum of strings

The value of variable will be the string that appears as follows.

ArcticHairdressing Saloon

We obtained a value of string type that, though formed absolutely correctly, looks strange. 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 (except assignment operations), variables are modified to a type of the highest priority, whereas before execution of assignment operations variables are modified to the target type.

Let us consider some problems that deal with typecasting.

icon_question

Problem 4 John has two pencils, whereas Pete went three times to the blackboard. How many in total?

As far as the formal logic is concerned, the incorrectness of the problem is obvious. It stands to reason that events cannot be added together with things; it is wrong.

icon_question

Problem 5 At one corner of the house, there is a grocery store named "Arctic," whereas John has two pencils. :)

With the same degree of hopelessness (as far as normal reasoning is concerned) we can ask, "How many in total?" Or, we can ask, "What is written on the house?" But, we cannot ask both questions.

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.

The data types int, bool, color, datetime, and double belong to the numeric data type. The internal representations of constants and variables of these type are numbers. Variables of int, bool, color, and datetime types are represented in computer memory as integers, whereas the variables of double type are represented as double-precision numbers with a floating point, that is real numbers. The value of constants and variables of string type is a set of characters (see Figure 16).

icon_attention

Values of int, bool, color, and datetime types are represented in computer memory as integers. Values of double type are represented in computer memory as real numbers. Values of string type are represented in computer memory as a sequence of characters. Values of int, bool, color, datetime, and double types are values of numeric type. Values of string type are values of character type.

Fig. 16. Representation of different data types in the computer memory.

Figure 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 computer memory as integers, whereas those of double type are represented 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.

icon_attention

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 typecast."

It is prohibited to cast the values of string type to any other target type.

Let us return to Problem 4. There can be two solutions for it.

Solution 4.1 We can make a calculation with the result as a value of int type.

double A = 2.0;                      // The number of John's pencils
int    Y = 3;                        // The number of Pete's passages
int    F = A + Y;                    // Total number

First of all, we need to know the value of the expression, provided its operands are of different types. In the following expression, operands of two data types are used; А is a double, and Y is an int.

A + Y

In compliance with the rule of implied typecasting, the value of this expression will be a number of double type. Please note that 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 a 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 cast 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 typecast. The final result of calculations and manipulations is that 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;                   // The number of John's pencils
int    Y = 3;                     // The number of Pete's passages
double F = A + Y;                 // Total number

This situation differs from the preceding one in that the target type of variable F (to the left of the assignment operation sign) is of double type, which coincides with the type of the expression A + Y, so we do not have any target typecast here. The result of the calculations (the value of the double-type variable F) is real number, 5.0.

Let us now find a solution for Problem 5. No questions come up at initialization of variables.

string W1 = "Arctic";               // String 1
double A  = 2;                      // The number of John's pencils

Solution 5.1 Here is a possible solution for this problem.

string W1  = "Arctic";             // String 1
double A   = 2;                    // Number of John's pencils
string Sum = W1 + A;               // Implied transformation to the right

Here, in the right part, we add together the values of two variables, one of string type, and 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). Then, the equi-type values will be added together. The resulting value to the right of the assignment operation sign will be a new string. This process of stringing together strings is called concatenation. 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.

Arctic2.00000000

Solution 5.2 The following 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 typecast for the values of string type. The type of the value of expression W1 + A is string, because of implied typecasting, like in the preceding example. When the assignment operation is executed, the target typecast must be performed. However, according to the rule, you cannot cast the string-type expression into a value with a lower priority type. This is an error that will be detected by MetaEditor at creation of the program, that is 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 numbers without a fractional part. If you add them together or subtract them, you will get an intuitive result. For example, assume the following is true.

int X = 2;                        // First int variable
int Y = 3;                        // Second int variable

And, assume the following is true.

int Z = X + Y;                    // Addition operation,

In this case, there is no problem to calculate the value of variable Z: 2 + 3 = 5.

Similarly, let us execute the following multiplication operation.

int Z = X * Y;                    // Multiplication operation,

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;                    // Division operation

It is easy to write 2 / 3. However, it is not an integer. So, what will be the value of expression X / Y and variable Z?

icon_attention

The rule of integer calculations is that the fractional part is always discarded.

In the above example, the expression to the right of the equality sign contains only integers, that is no typecasting takes place. 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, in the following lines of code, the value of 7 / 3 for the expression X / Y and variable Z is equal to 2.

int X = 7;                      // The value of an int variable
int Y = 3;                      // The value of an int variable
int Z = X / Y;                  // Division operation,

Order of operations

The calculating rule is the following.

icon_attention

The value of an expression is calculated according to the priorities of arithmetical operations, and from left to right, each intermediate outcome being calculated according to the typecasting rules.

Let us consider the calculating order for an expression in the following example:

Y = 2.0 * ( 3 * X / Z - N) + D;                          // Exemplary expression

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, consists of two summands. The summand 3 * X / Z consists of three factors, namely 3, X, and Z.

In order to calculate the expression to the right of 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 from 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, we will calculate the value of the expression 2.0 * ( 3 * X / Z - N). Last, we will calculate the value 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, in a program, calculations must take into account the types of values in intermediate outcomes, which exercises a significant influence on the final result of calculations. Particularly, the order of operands in an expression is very important (unlike the rules accepted in mathematics). To demonstrate this, let us consider a small example.

icon_question

Problem 6 Calculate the values of expressions А / В * С and А * С / В for integers А, В, and С.

The result of the 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. The sequence of operands is of fundamental importance.

int A = 3;                          // Value of int type
int B = 5;                          // Value of int type
int C = 6;                          // Value of int type
int Res_1 = A / B * C;                  // Result 0 (zero)
int Res_2 = A * C / B;                  // Result 3 (three)

Let us 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 С) results in integer 0 (zero).

3. The general result (the value of the variable Res_1) is integer 0 (zero).

Let us now follow the developments of calculating the expression A * C / B.

1. The calculation of A * C produces integer 18 (3 * 6 = 18).

2. Calculation of the expression 18 / B produces an obvious answer; after the fractional part has been discarded, (18 / 5) is integer 3 (three).

3. The general result (the value of variable Res_2) is integer 3 (three).

In the preceding 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 operators section, the term and general properties of operators are considered, whereas the special properties of each operator are described in the chapter named Operators.