Java - Simple cuestión teórica

   
Vista:

Simple cuestión teórica

Publicado por Daniel (1 intervención) el 04/10/2014 19:12:07
Hola a todos, tengo una pequeña duda en Java, es más una cuestión teórica que práctica:

Según he podido leer en varios libros de Java el operador lógico (AND) && tiene una valor de precedencia más alto que (OR) ||.

Sin embargo me encuentro este sencillo ejercicio, donde parece ser que el orden de precedencia no se cumple:

int a = 2;
int b = 4;
if(a < 3 || b <10 && b< 4/0)
{
System.out.println("Estoy dentro");
}

El programa compila y muestra el mensaje correctamente, puesto que se basa en el hecho de la evaluación en cortocircuito. Y como a<3 es cierto cualquier cosa después del || (OR) también lo será.

Sin embargo, espera que diese un error en tiempo de ejecuación, pues si realmente (AND) && tiene mayor procedencia que (OR) || se tendría que evaluar primero b<10 && b<4/0 y puesto que se está cometiendo un error lógico al dividir entre cero devería dar un error. Pero como he comentado anteriormente aplica el criterio de evaluación en cortocircuito, ergo no entiendo porque evalúa primero (a<3) || ... y no (b<10) && si el operador AND tiene más procedencia.

¿Cuál es la explicación al respecto?

Gracias a todos y un Saludo.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Simple cuestión teórica

Publicado por Tom (910 intervenciones) el 04/10/2014 20:06:20
Pues ya lo estás diciendo tú :D Se aplica el cortocircuito en el primer OR. Hay algo que no has tenido en cuenta, y es la evaluación de izquierda a derecha.

Tu prueba es equivalente a:

1
if((a < 3) || ((b <10) && (b< 4/0)))
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Pedro (81 intervenciones) el 04/10/2014 20:07:00
Hasta donde llegan mis conocimientos en Java, AND y OR tienen el mismo valor de precedencia por lo que la expresión se evalúa de izquierda a derecha.

Para que lo puedas verificar de forma experimental puedes hacer lo siguiente.

1
2
3
4
5
6
7
8
int a = 2;
int b = 4;
int[] c = new int[2];
 
if(a < c[3] | b <10 & b< 4/0)
{
     System.out.println("Estoy dentro");
}

Si la excepción es porque el indice del array no existe, esos libros se equivocan, si es por dividir entre cero están en lo cierto.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Tom (910 intervenciones) el 04/10/2014 20:23:45
Ah! ... y aunque realmente es escasa la explicación, está aquí:

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Copio y pego:

"When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left."
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Daniel (1 intervención) el 04/10/2014 21:12:10
Gracias por vuestras respuesta.

En primer lugar he visto la tabla de precedencia y efectivamente and tiene mayor precedencia que or, también sé que la evaluación es de izquierda a derechas (siempre y cuando las operaciones tengan el mismo valor de precedencia).

Por eso si tengo: if(a<3 || b<10 && b<4/0)

Entiendo que los pasos a seguir son:

1) Mirar en la condición la precedencia de las expresiones si son iguales sé que va de izquierda a derechas pero como && tiene más precedencia entonces debería evaluar primero. b<10 && b<4/0.
Luego b<10 (Cierto).
b<4/0 (Error).

Y sin embarglo lo que hacer es:

1) Evalua a<3 (Cierto).(¿?)
2) Como a<3 es cierto y luego está el operador OR entonces toda la expresión es cierta.

Pero sigo sin entender porqué evalua primero a<3 aunque se haga de izquierda a derechas la evaluación si hay una expresión con mayor precedencia.

Gracias y Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Pedro (81 intervenciones) el 05/10/2014 10:01:41
Yo creo que la tabla no se aplica a operadores lógicos, ya que te dice que todos los operadores binarios se ejecutan de izquierda a derecha salvo los de asignación por lo que la precedencia de la tabla no tiene efecto sobre ellos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Daniel (1 intervención) el 05/10/2014 16:38:59
Pero si la tabla no se aplica a operadores lógicos entonces por qué muestra:

Operadores de precedencia:
____________________________________________________________________________________

Operadores Precedencia
.........
lógica AND &&

lógica OR ||
........
_____________________________________________________________________________________

Si AND Y OR son operadores lógicos ¿?

Gracias a todos por vuestra ayuda.
Es una cuestión que no me supone un gran problema, pero no acabo de enterderlo realmente.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Tom (910 intervenciones) el 05/10/2014 19:51:16
La frase no dice exactamente que la regla de izquierda a derecha se aplique cuando hay operadores de la misma precedencia (no puse bien la negrita :)). Ten en cuenta que la siguiente frase está separada por '.'.
La regla que debe gobernar la evaluación es, que yo sepa, el uso de paréntesis, aunque no lo diga ahí.

Se entiende cuando llevas tiempo programando.
Piensa en qué es una expresión "binaria": "Operando Izquierdo (LT) / Operador (OP) / Operando Derecho (RT)"

Pues si tienes una expr : "a < 3 || b < 10 ..." el primer OP que te encuentras es el operador <, sigues examinando la expresión para decidir cual es el LT y cual el RT, y te encuentras el operador ||, que tiene menor precedencia que <. Pues ya está claro, la primera subexpresión que tienes que evaluar es a < 3 (obtienes true) .
Sigues examinando y te encuentras el operador || ; Así tienes una nueva expr con LT true, con OP || y con RT la expr b < 10 ... Ahí ya no se evalúa más.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Simple cuestión teórica

Publicado por Daniel (1 intervención) el 05/10/2014 21:53:27
Ok gracias Tom, y a todos por vuestra ayuda.

Esta última explicación me deja las cosas más claras, (tenía otro enfoque al respecto).

Un saludo y gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar