2009-03-01 22 views
47

A menudo uso ($var & 1) en mi código, que devuelve verdadero si $var es un número impar y falso si es un número par.Descripción de PHP & (comercial, bit a bit y) operador

¿Pero qué significa "&" en realidad?

+0

Para algunos la pregunta no es simple, y él está pidiendo una explicación detallada sobre el operador, como puede ver por la respuesta que aceptó. –

+0

@Olafur - el operador & es bastante simple. Él no quiere una explicación detallada, quiere una explicación AN, porque la ha estado usando sin saber qué es exactamente lo que hace. Si bien admiro su voluntad de admitir que él no lo sabe y desea aprenderlo, sigue siendo una cuestión de Google. –

+0

No se trata de si la respuesta es simple, pero si publicarla aquí significa simplemente copiarla desde otro lugar. Esto es redundante. Me parece que algunas personas realmente están usando SO para matar el tiempo libre. Tal vez soy un poco parcial, pero me gustan los acertijos y no las preguntas tipo chat. – Caffeine

Respuesta

52

& es and binario. Si tiene un valor binario y tiene and con otro valor binario, el resultado será el bit and de los dos. Un ejemplo:

01101010 
& 01011001 
= 01001000 

El bit más a la derecha es o bien un 1 (y en ese caso el número es un número impar) o es un 0, en cuyo caso el número es par. Si & un número con 1, solo mira el bit menos significativo, y si comprueba si el número es 1 o 0. Como han mencionado otros, mire a los operadores bit a bit para obtener información sobre cómo funcionan.

18

Esto también es interesante saber acerca bit a bit y PHP:

/** 
* Regular 
*/ 
echo (true && true); // 1 
echo (true && false); // nothing 

echo (true || false); // 1 
echo (false || false); // nothing 

echo (true xor false); // 1 
echo (false xor false); // nothing 

/** 
* Bitwise 
*/ 
echo (true & true); // 1 
echo (true & false); // 0 

echo (true | false); // 1 
echo (false | false); // 0 

echo (true^false); // 1 
echo (false^false); // 0 
+1

Esta respuesta realmente no explica cómo && es diferente y muy bueno en mi opinión. && arroja ambos parámetros a booleano, y es como comparar un solo bit. & se compara en una forma bit a bit: cada bit en un parámetro se compara con cada bit en el otro. – thomasrutter

+3

"regular" se conoce como lógica y/o –

+1

También es importante saber que los operadores bit a bit como & y | operar en enteros. Los ejemplos en esta respuesta solo funcionan porque 'true' convierte a' 1' y 'false' convierte a' 0'. Si tuvieras 'echo (" cheese "& 4)' obtendría cero, mientras que 'echo (" cheese "&& 4)' daría como resultado verdadero. – thomasrutter

24

dos operaciones que son fundamentales para los sistemas binarios son OR y AND.

O significa 'si A está encendido o B está encendido'. Un ejemplo del mundo real sería dos interruptores en paralelo. Si cualquiera permite la corriente, la corriente pasa.

AND significa 'si ambos A y B están activados'. El ejemplo del mundo real es dos interruptores en serie. La corriente solo pasará si ambos permiten la corriente.

En una computadora, estos no son interruptores físicos sino semiconductores, y su funcionalidad se llama logic gates. Hacen las mismas cosas que los interruptores: reaccionan a la corriente o no a la corriente.

Cuando se aplica a enteros, cada bit de un número se combina con cada bit del otro número. Entonces, para entender los operadores de bit O y Y, necesitas convertir los números a binarios, luego haz la operación OR o AND en cada par de bits coincidentes.

Esa es la razón por:

00011011 (odd number) 
AND 
00000001 (& 1) 
== 
00000001 (results in 1) 

Considerando

00011010 (even number) 
AND 
00000001 (& 1) 
== 
00000000 (results in 0) 

Por consiguiente, el (& 1) operación compara el derecho más bits a 1 usando y la lógica. Todos los otros bits son ignorados efectivamente porque cualquier cosa Y nada es nada. Un número par en binario también es un número par en notación decimal (10 es un múltiplo de 2).

Otras operaciones fundamentales de los sistemas binarios incluyen NOT y XOR. NO significa 'si A está desactivado' y es la única forma de puerta lógica que toma solo una señal o 'parámetro' en lugar de dos. XOR significa 'si A o B están activados, pero no ambos'. Y luego están NAND, NOR y NXOR, que básicamente NO se combinan con AND, OR y XOR, es decir, NAND significa 'si A y B son no ambos en'.

En la programación, el operador

& means AND, 
| means OR, 
~ means NOT, and 
^ means XOR. 

Los otros se pueden hacer mediante la combinación de estos, por ejemplo:

~ (a & b) is equivalent to a NAND operation 

PHP nota específica

bit a bit operadores no funcionan en valores de coma flotante, y en los valores flotantes de PHP se convertirán implícitamente en enteros primero. Los números fuera del rango que pueden expresarse como enteros se truncarán a cero, es decir, todos los números sobre PHP_INT_MAX se verán "pares" en la expresión ($num & 1)). Si desea admitir números fuera de PHP_INT_MIN/PHP_INT_MAX, necesitará fmod($num, 2). Sin embargo, si tiene PHP de 64 bits, sus enteros tendrán una mayor precisión que los flotadores de todos modos.

+2

Personalmente, creo que esto explica el problema mejor que la respuesta aceptada, ya que realmente explica qué operaciones a nivel de bit detrás del escenario, lo cual es "crucial" para comprenderlas y usarlas. – Byson

11

Sé que su pregunta es sobre la comprensión del operador bit a bit y la respuesta aceptada lo explica bien. Sin embargo, por el ejemplo que da, no puedo ayudar, pero recomendando que utilice el operador módulo en su lugar:

($var % 2) /* instead of */ ($var & 1) 

porque hace que la clara intención de que se está comprobando que el número es impar (no divisible por dos), y es más genérico, por lo que puede utilizar ($ var% 3) de la misma manera y deducir cómo funciona para cualquier N.

11

Además de las otras respuestas, vale la pena señalar que

if(func1() && func2()) 

sólo se llame al func2() si func1() devuelve verdadero ("la Evaluación zy "), mientras que

if(func1() & func2()) 

llamaremos ambas funciones con independencia, pero las tablas de verdad para ambos será el mismo (suponiendo que vuelvan booleanos).


thomasrutter señala (en los comentarios) que probablemente no debería hacer esto último en la práctica. (A & B) no necesariamente tendrá la misma veracidad que (A && B), particularmente cuando A y B son enteros. por ejemplo, si A = 1 y B = 2 (ambos son verdaderos), A & B será falsey, mientras que A & & B es verdad. Además, otro desarrollador puede pensar que se trata de un error tipográfico y 'corregir' a dos ampersands.

+1

+1, esto es muy interesante y desconocido para todos – dgraziotin

+0

Importante distinción. –

+1

Si bien esto funciona * la mayor parte del tiempo *, no siempre funcionará, como cuando las funciones devuelven números. Digamos que func1() devuelve 1 y func2() devuelve 4. 'func1() && func2()' evaluará a 'true' mientras' func1() & func2() 'evaluará a' 0'. Incluso en los casos en que sí funciona, no lo llamaría una buena práctica de codificación ya que depende de los efectos secundarios del orden de evaluación y de la conversión de tipo, lo que hace más difícil leer y comprender el propósito del código. Cualquier persona que revise el código puede asumir que es un error tipográfico. – thomasrutter