- Conceptos básicos
- Operaciones de asignación
- Operaciones aritméticas
- Incremento y decremento
- Operaciones de comparación
- Operaciones lógicas
- Operaciones a nivel de bits
- Operaciones de modificación
- Operador ternario condicional
- Coma
- Operadores especiales sizeof y typename
- Agrupación con paréntesis
- Prioridades de las operaciones
Operaciones de comparación
Como su nombre indica, estas operaciones están pensadas para comparar dos operandos y devolver una función lógica, true o false, dependiendo de la condición que se deba mantener en la comparación.
En la siguiente tabla se muestran todas las operaciones de comparación y sus propiedades, tales como símbolos utilizados, prioridades, ejemplos y asociatividad.
P |
Símbolos |
Descripción |
Ejemplo |
Orden de ejecución |
---|---|---|---|---|
6 |
< |
Menos |
e1 < e2 |
I-D |
6 |
> |
Mayor |
e1 > e2 |
I-D |
6 |
<= |
Menor o igual que |
e1 <= e2 |
I-D |
6 |
>= |
mayor o igual que |
e1 >= e2 |
I-D |
7 |
== |
Igualdad |
e1 == e2 |
I-D |
7 |
!= |
No es igual |
e1 != e2 |
I-D |
El principio de cada operación es comparar dos operandos utilizando el criterio de la columna que contiene su descripción. Por ejemplo, la entrada «x < y» significa comprobar si «x es menor que y». En consecuencia, el resultado de la comparación será true si x es realmente menor que y, y false en todos los demás casos.
Las comparaciones funcionan para operandos de cualquier tipo (para tipos diferentes se realiza una conversión de tipos).
Teniendo en cuenta la asociatividad izquierda y la devolución del resultado de tipo bool, construir una secuencia de comparaciones no funciona de forma tan obvia. Por ejemplo, una expresión hipotética para comprobar si el valor y se encuentra entre los valores de x y z, podría aparecer de la siguiente manera:
int x = 10, y = 5, z = 2;
|
Sin embargo, dicha expresión se procesa de manera diferente. Hasta el compilador lo distingue con el aviso «Uso inseguro del tipo 'bool' en la operación».
Debido a la asociatividad izquierda, la condición izquierda x < y se comprueba primero, y su resultado se sustituye como valor temporal del tipo bool en la expresión que se desarrolla de la siguiente manera: b < z. A continuación, el valor de z se compara con true o false en la variable temporal b. Para comprobar si y se encuentra entre x y z debe utilizar dos operaciones de comparación combinadas con la operación lógica AND (se analizará en la sección siguiente).
int x = 10, y = 5, z = 2;
|
Al utilizar la comparación para igualdad/desigualdad se tendrán en cuenta las características de los tipos de operandos. Por ejemplo, los números de punto flotante contienen a menudo valores «aproximados» después de los cálculos (hemos tenido en cuenta la precisión de la representación de double y float en la sección Números reales). Por ejemplo, la suma de 0.6 y 0.3 no es 0.9 en sentido estricto:
double p = 0.3, q = 0.6;
|
La diferencia hace 1*10-16, pero es suficiente para que la operación de comparación devuelva false.
Por lo tanto, los números reales deben compararse para ver su igualdad o desigualdad utilizando los operadores mayor-/menor-entonces para averiguar su diferencia y desviación aceptable que se determina manualmente, basándose en las características del cálculo, o se toma una universal. Recordemos que para double y float se definen las constantes de precisión integradas, DBL_EPSILON y FLT_EPSILON, válidas para el valor 1.0. Deben escalarse para comparar otros valores. En el guión ExprRelational.mq5 se presenta una de las posibles realizaciones de la función isEqual para comparar números reales, que considera este aspecto.
bool isEqual(const double x, const double y)
|
Aquí utilizamos la función de obtener un valor absoluto sin signo (MathAbs) y el mayor de los dos valores (MathMax). Se describirán en la sección Funciones matemáticas de la Parte 4. La diferencia absoluta entre los parámetros de la función isEqual se compara con la tolerancia calibrada en la variable eps mediante la operación '<'.
En cualquier caso, esta función no puede utilizarse para comparar con el cero absoluto. Para ello, puede utilizar el siguiente planteamiento (probablemente requerirá alguna adaptación a sus necesidades específicas):
bool isZero(const double x)
|
Las cadenas se comparan lexicográficamente, es decir, letra por letra. El código de cada carácter se compara con el código del carácter situado en la misma posición de la segunda cadena. La comparación se realiza hasta que se encuentra una diferencia en los códigos o una de las cadenas termina. La proporción de la cadena será igual a la de los primeros caracteres diferentes, o se considerará que una cadena más larga es mayor que la más corta. Recuerde que las mayúsculas y las minúsculas tienen códigos diferentes y, por extraño que parezca, las mayúsculas tienen códigos más pequeños que las minúsculas.
Una cadena vacía "" (de hecho, almacena un terminal 0) no es igual al valor especial de NULL que significa que no hay cadena.
bool cmp1 = "abcdef" > "abs"; // false, [2]: 's' > 'c'
|
Además, para comparar cadenas, MQL5 proporciona algunas funciones que se describirán en la sección Trabajar con cadenas.
Al comparar por igualdad/desigualdad, no se recomienda utilizar constantes bool : true o false. La cuestión es que, en expresiones como v == true o v == false, el operando v puede interpretarse intuitivamente como un tipo lógico, mientras que en realidad es un número. Como es sabido, el valor cero se considera false en los números, mientras que todos los demás se interpretan como true (a menudo queremos utilizarlo como indicación de que algún resultado está presente o ausente). Sin embargo, en este caso, la conversión de tipos va hacia atrás: true o false se «expanden» a un tipo numérico v y se hacen de hecho iguales a 1 y 0, respectivamente. Una comparación de este tipo tendrá un resultado distinto del esperado (por ejemplo, la comparación 100 == true resultará falsa).