2011-07-01 21 views
5

Supongamos que tenemos 3 variables y tenemos que AFIRMAR que todas pueden ser iguales a -1 o ninguna puede ser igual a -1. Escribí el siguiente código:Evaluación de la expresión de la igualdad triple

x := 1; 
y := 1; 
z := 1; 

ASSERT((x = -1) = (y = -1) = (z = -1)); 

A menudo escribo este tipo de verificación, pero para dos variables. Sorprendentemente, la comparación triple compilada también, pero no funciona como se esperaba. Para los valores (1, 1, 1), espero que se evalúe como verdadero. Después de la sustitución de los valores de las variables y la simplificación obtenemos:

ASSERT(False = False = False); 

y pensé que debería evaluarse como True, pero no es así. Entonces, ¿cómo se evalúa esta comparación triple?

+0

¿Ninguno? ¿Cómo es posible con 3 condiciones? –

+0

+1 por la rareza de la expresión! Si tuviera cualquier otro valor booleano, obtendría un error de compilador de 'Tipos incompatibles'; Y supongo que este es un caso de esquina ya que los valores de BOOLEAN rara vez se comparan con el operador '='. –

+2

Nada es extraño, Falso = Falso es igual a Verdadero, y Verdadero <> Falso –

Respuesta

8

Antes que nada, el operador = es un operador binario: siempre funciona en un par de valores. Entonces, no hay tal cosa como una "triple igualdad". El compilador evaluará un par y usará el resultado para evaluar el otro.

Cuando el compilador ve múltiples operadores vinculados, necesita agruparlos en pares utilizando lo que se denomina "precedencia de los operadores". Está claro si piensas en los operadores aritméticos básicos que aprendimos en la escuela primaria. No hay duda de qué: 3+2*4 evalúa como: es equivalente a 3+(2*4). En caso de duda, siempre agregue la agrupación usted mismo. Si lo hace, usted ve a su expresión es equivalente a:

((False = False) = False), y es obvio que se evalúa como:

(True = False).

Lo que probablemente desea es utilizar el operador AND y el grupo de su inicial Assert así:

ASSERT(((x = -1) = (y = -1)) and ((y = -1) = (z = -1)))

Entonces yo probablemente sea escribir esa expresión en varias líneas para que el operador AND obvia (hábito de SQL, lo sé), o reescribir por completo:

Assert (
    ((x = -1) = (y = -1)) 
    and 
    ((x = -1) = (z = -1)) 
); 

o esta variante:

Assert (
    ((x = -1) and (y = -1) and (z = -1)) 
    or 
    ((x <> -1) and (y <> -1) and (z <> -1)) 
); 

Mi regla es: si se necesita más de 1 segundo para determinar la precedencia de los operadores, agregue paréntesis.

+3

+1 para "Mi regla". –

2

Comparación es asociativa: False = False = False es equivalente a (False = False) = False. La primera Falso = False se evalúa como verdadera , lo que lleva a la comparación True = Falso que a su vez es Falso.

Cuestiones relacionadas