Often a necessity occurs to convert one numeric type into another. Not all numeric types can be converted into another. Here is the scheme of allowed casting:
Solid lines with arrows indicate changes that are performed almost without any loss of information. Instead of the char type, the bool type can be used (both take 1 byte of memory), instead of type int, the color type can be used (4 bytes), instead of the long type, datetime can be used (take 8 bytes). The four dashed grey lines, also arrowed, denote conversions, when the loss of precision can occur. For example, the number of digits in an integer equal to 123456789 (int) is higher than the number of digits that can be represented by float.
A number converted into float has the same order, but is less accurate. Conversions, contrary to black arrows, can be performed with possible data loss. Conversions between char and uchar, short and ushort, int and uint, long and ulong (conversions to both sides), may lead to the loss of data.
As a result of converting floating point values to integer type, the fractional part is always deleted. If you want to round off a float to the nearest whole number (which in many cases is more useful), you should use MathRound().
If two values are combined by a binary operator, before the operation execution the operand of a lower type is converted to the higher type in accordance with the priority given in the below scheme:
The data types char, uchar, short, and ushort unconditionally are converted to the int type.
The calculated expression consists of two operations. In the first example, the variable c1 of the char type is converted to a temporary variable of the int type, because the second operand in the division operation, the constant 2, is of the higher type int. As a result of the integer division 3/2 we get the value 1, which is of the int type.
In the second operation of the first example, the second operand is the constant 0.3, which is of the double type, so the result of the first operation is converted into a temporary variable of the double type with a value of 1.0.
In the second example the variable of the char type c1 is converted to a temporary variable of the double type, because the second operand in the division operation, the constant 2.0, is of the double type; no further conversions are made.
In the expressions of the MQL5 language both explicit and implicit typecasting can be used. The explicit typecasting is written as follows:
An expression or function execution result can be used as the var_2 variable. The function style notation of the explicit typecasting is also possible:
Let's consider an explicit typecasting on the basis of the first example.
Before the division operation is performed, the c1 variable is explicitly cast to the double type. Now the integer constant 2 is cast to the value 2.0 of the double type, because as a result of converting the first operand has taken the double type. In fact, the explicit typecasting is a unary operation.
Besides, when trying to cast types, the result may go beyond the permissible range. In this case, the truncation occurs. For example:
Before operations (except for the assignment ones) are performed, the data are converted into the maximum priority type. Before assignment operations are performed, the data are cast into the target type.
When converting long/ulong type into double, precision may be lost in case the integer value is greater than 9223372036854774784 or less than -9223372036854774784.
The string type has the highest priority among simple types. Therefore, if one of operands of an operation is of the string type, the second operand will be cast to a string automatically. Note that for a string, a single dyadic two-place operation of addition is possible. The explicit casting of string to any numeric type is allowed.
Data of the simple structures type can be assigned to each other only if all the members of both structures are of numeric types. In this case both operands of the assignment operation (left and right) must be of the structures type. The member-wise casting is not performed, a simple copying is done. If the structures are of different sizes, the number of bytes of the smaller size is copied. Thus the absence of union in MQL5 is compensated.
Another example illustrates the method of organizing a custom function for receiving RGB (Red, Green, Blue) representation from the color type. Create two structures of the same size but with different contents. For convenience, let's add a function returning the RGB representation of a color as a string.
Objects of the open generated class can also be viewed as objects of the corresponding base class. This leads to some interesting consequences. For example, despite the fact that objects of different classes, generated by a single base class, may differ significantly from each other, we can create a linked list (List) of them, as we view them as objects of the base type. But the converse is not true: the base class objects are not automatically objects of a derived class.
You can use the explicit casting to convert the base class pointers to the pointers of a derived class. But you must be fully confident in the admissibility of such a transformation, because otherwise a critical runtime error will occur and the mql5 program will be stopped.
Dynamic typecasting is performed using dynamic_cast operator that can be applied only to pointers to classes. Type validation is performed at runtime. This means that the compiler does not check the data type applied for typecasting when dynamic_cast operator is used. If a pointer is converted to a data type which is not the actual type of an object, the result is NULL.
The type-id parameter in angle brackets should point to a previously defined class type. Unlike C++, expression operand type can be of any value except for void.