2010-10-25 23 views

Respuesta

104

Esos son los operadores O bit a bit Y.

int a = 6; // 110 
int b = 4; // 100 

// Bitwise AND  

int c = a & b; 
// 110 
// & 100 
// ----- 
// 100 

// Bitwise OR 

int d = a | b; 
// 110 
// | 100 
// ----- 
// 110 

System.out.println(c); // 4 
System.out.println(d); // 6 

Gracias a Carlos para señalar el apartado correspondiente en el lenguaje Java Spec (15.22.1, 15.22.2) con respecto a los diferentes comportamientos del operador basado en sus entradas.

De hecho cuando ambas entradas son del tipo booleano, los operadores se consideran los operadores lógicos booleanos y se comportan similar a la condicional-Y (&&) y condicional-O (||) los operadores excepto por el hecho de que no cortocircuito así, mientras que la siguiente es segura:

if((a != null) && (a.something == 3)){ 
} 

Esto no es:

if((a != null) & (a.something == 3)){ 
} 
+1

quería aclarar ... ¿y devolverá 1 solo si AMBOS son 1? ¿Entonces 101 y 001 serían 001? ¿Derecha? – gideon

+0

@giddy correcto. –

+0

@giddy @Jonathon - Actualicé mis valores para mostrar mejor esa situación. –

6

los operadores & & y || están en cortocircuito, lo que significa que no evaluarán su expresión de la mano derecha si el valor de la expresión de la mano izquierda es suficiente para determinar el resultado.

+6

-1 por decirle al OP lo que él ya sabía y no responder la pregunta que en realidad le hizo. – Alnitak

3

& y | proporciona el mismo resultado que el & & y || operadores. La diferencia es que siempre evalúan ambos lados de la expresión donde como & & y || deje de evaluar si la primera condición es suficiente para determinar el resultado.

+3

Mismo resultado -para booleanos- ... – KarlP

+1

Incorrecto .... Para '&&' evalúa ambos resultados mientras que '||' solo regresa si la primera condición es verdadera. –

+1

¿Eh? El && solo evalúa el lado derecho de la expresión si el lado izquierdo ya se evalúa como verdadero. De lo contrario, deja de evaluar ya que el primer falso implica implícitamente que el resultado no puede ser cierto. Consulte http://www.jguru.com/faq/view.jsp?EID=16530 –

94

creo que está hablando el significado lógico de ambos operadores, aquí se tiene una tabla de hoja de vida:

boolean a, b; 

Operation  Meaning      Note 
---------  -------      ---- 
    a && b  logical AND     short-circuiting 
    a || b  logical OR      short-circuiting 
    a & b  boolean logical AND   not short-circuiting 
    a | b  boolean logical OR    not short-circuiting 
    a^b  boolean logical exclusive OR 
    !a   logical NOT 

short-circuiting  (x != 0) && (1/x > 1) SAFE 
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE 
+1

@Torres - Amplíe su respuesta explicando "cortocircuito" y "seguro". ¿También es "exclusivo" o "lógico no" y "no cortocircuito"? ¿Y por qué se llama "lógico no" en lugar de "booleano lógico no"? ¿Y por qué el "NO lógico" no está agrupado con "Y lógico" y "OR lógico"? Buena respuesta pero necesita trabajo. – tfmontague

+0

@tfmontague, he explicado qué significa el cortocircuito (editando esta respuesta). Esperando a que mi edición sea "revisada por pares". – Taslim

1

tal vez puede ser útil saber que la operación AND y OR bit a bit operadores son siempre evaluado antes de Y condicional y O condicional usado en la misma expresión.

if ((1>2) && (2>1) | true) // false! 
+1

¿se refiere a la prioridad del operador en lugar de a la orden de evaluación? Preferiría no ver la diferencia de prioridad utilizada en el código real. Use paréntesis en lugar de operadores bit a bit para este propósito. –

0

Si se evalúa una expresión booleana que implica la & operador, se evalúan los dos operandos. Luego, el operador & se aplica al operando.

Cuando se evalúa una expresión que considera el operador & &, se evalúa el primer operando. Si el primer operando se evalúa como falso, se omite la evaluación del segundo operando.

Si el primer operando devuelve un valor verdadero, se evalúa el segundo operando.Si el segundo operando devuelve un valor verdadero, entonces el operador & & se aplica al primer y segundo operandos.

Similares para | y ||.

0

Mientras que la diferencia básica es que & se utiliza para operaciones bit a bit sobre todo en long, int o byte donde puede ser utilizado para una especie de máscara, los resultados pueden diferir incluso si lo usa en lugar de lógica &&.

La diferencia es más notable en algunos escenarios:

  1. Evaluación de algunas de las expresiones es mucho tiempo
  2. Evaluación de uno de la expresión se puede hacer sólo si la anterior era cierto
  3. Las expresiones tener algún efecto secundario (previsto o no)

El primer punto es bastante sencillo, no causa errores, pero lleva más tiempo. Si tiene varias comprobaciones diferentes en una instrucción condicional, coloque aquellas que son más baratas o más propensas a fallar a la izquierda.

Para segundo punto, véase este ejemplo:

if ((a != null) & (a.isEmpty())) 

Esta falla por null, como la evaluación de la segunda expresión produce una NullPointerException. El operador lógico && es flojo, si el operando izquierdo es falso, el resultado es falso sin importar el operando correcto.

Ejemplo para el tercer punto: digamos que tenemos una aplicación que usa DB sin desencadenantes ni cascadas. Antes de eliminar un objeto Building, debemos cambiar el edificio de un objeto Department por otro. Digamos también que el estado de la operación se devuelve como un booleano (verdadero = éxito). Luego:

if (departmentDao.update(department, newBuilding) & buildingDao.remove(building)) 

Esto evalúa ambas expresiones y, por lo tanto, lleva a cabo la eliminación del edificio, incluso si la actualización del departamento falló por alguna razón. Con &&, funciona según lo previsto y se detiene después de la primera falla.

En cuanto a a || b, es equivalente a !(!a && !b), se detiene si a es verdadero, no se necesitan más explicaciones.

2

En Java, los operadores individuales &, |, ^,! depende de los operandos. Si ambos operandos son enteros, entonces se realiza una operación bit a bit. Si ambos son booleanos, se realiza una operación "lógica".

Si ambos operandos no coinciden, se produce un error de tiempo de compilación.

Los operadores dobles & &, || comportan de manera similar a sus contrapartes individuales, pero ambos operandos deben ser expresiones condicionales, por ejemplo:

si ((a < 0) & & (b < 0)) {...} o de manera similar, si ((una < 0) || (b < 0)) {...}

fuente: java de programación lang 4ª ed

1

& &; || son operadores lógicos .... cortocircuito

&; | son operadores lógicos booleanos .... No cortocircuito

Pasando a las diferencias en la ejecución de las expresiones. Los operadores bit a bit evalúan ambos lados independientemente del resultado del lado izquierdo. Pero en el caso de evaluar expresiones con operadores lógicos, la evaluación de la expresión de la mano derecha depende de la condición de la mano izquierda.

Por ejemplo:

int i = 25; 
int j = 25; 
if(i++ < 0 && j++ > 0) 
    System.out.println("OK"); 
System.out.printf("i = %d ; j = %d",i,j); 

Esto imprimirá i = 26; j = 25, A medida que la primera condición es falsa la condición de la mano derecha se pasa por alto como el resultado es falso de todos modos, independientemente de la condición lado derecho (cortocircuito)

int i = 25; 
int j = 25; 
if(i++ < 0 & j++ > 0) 
    System.out.println("OK"); 
System.out.printf("i = %d ; j = %d",i,j); 

Pero, esto imprimirá i = 26.; j = 26,

15

Sé que hay muchas respuestas aquí, pero todas parecen un poco confusas. Así que después de investigar un poco de la guía de estudio de Oracle Oracle, he llegado a tres escenarios diferentes de cuándo usar & & o &. Los tres escenarios son lógico Y, en bits Y, y booleano Y.

Y lógico: Y lógico (también conocido como condicional y) utiliza el operador & &. Su significado es cortocircuitado: si el operando de la izquierda es falso, entonces el operando de la derecha no será evaluado.
Ejemplo:

int x = 0; 
if (false && (1 == ++x) { 
    System.out.println("Inside of if"); 
} 
System.out.println(x); // "0" 

En el ejemplo anterior el valor impreso a la consola de x será 0, debido a que el primer operando en la sentencia if es falsa, por lo tanto, Java no tiene necesidad de calcular (1 == ++ x) por lo tanto, x no se computará.

AND bit a bit: AND bit a bit usa el operador &. Se usa para preformar una operación bit a bit en el valor. Es mucho más fácil ver lo que está pasando examinado operación en números binarios por ejemplo:

int a = 5;  //     5 in binary is 0101 
int b = 12; //     12 in binary is 1100 
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4 

Como se puede ver en el ejemplo, cuando las representaciones binarias de los números 5 y 12 están alineados, a continuación, un AND bit a bit preformado producirá solamente un número binario, donde el mismo dígito en ambos números tienen un 1. por lo tanto 0101 & 1100 == 0100. lo que en decimal es 5 & 12 == 4.

booleana AND: Ahora el booleano El operador AND se comporta de manera similar y diferente tanto con el AND a nivel de bit como con el Y lógico.Me gusta pensar que se está preformando un AND a nivel de bit entre dos valores booleanos (o bits), por lo tanto, usa el operador &. Los valores booleanos también pueden ser el resultado de una expresión lógica.

Devuelve un valor verdadero o falso, al igual que el AND lógico, pero a diferencia del AND lógico y no está cortocircuitado. La razón es que, para que preforma ese Y a nivel de bit, debe conocer el valor de los operandos izquierdo y derecho. He aquí un ejemplo:

int x = 0; 
if (false & (1 == ++x) { 
    System.out.println("Inside of if"); 
} 
System.out.println(x); //"1" 

Ahora, cuando que si se corrió comunicado, la expresión (1 == ++ x) se ejecutará, a pesar de que el operando de la izquierda es falsa. Por lo tanto, el valor impreso para x será 1 porque se incrementó.

Esto también se aplica a OR lógico (||), bit a bit O (|), y booleano O (|) Espero que esto aclare un poco de confusión.

+0

ejemplo perfecto. Gracias. –

+0

'para preformar ese bit Y, debe conocer el valor de los operandos izquierdo y derecho. Esto no me suena bien. Para realizar un 'BITWISE AND' no necesita conocer el operando correcto para poder deducir el resultado si el operando de la izquierda es' FALSE'. Lo que explicas es correcto, pero el razonamiento que dices no lo parece, al menos para mí ... –

Cuestiones relacionadas