2009-03-01 22 views
47

Io uso spesso ($var & 1) nel mio codice, che restituisce true se $var è un numero dispari e falso se è un numero pari.Comprendere l'operatore PHP e (e commerciale, bit a bit e)

Ma cosa fa effettivamente "&"?

+0

Per alcuni la domanda non è semplice, e chiede una spiegazione dettagliata dell'operatore, come puoi vedere dalla risposta che ha accettato. –

+0

@Olafur - l'operatore & è abbastanza semplice. Non vuole una spiegazione dettagliata, vuole una spiegazione, perché lo sta usando senza sapere esattamente cosa fa. Mentre ammiro la sua volontà di ammettere che non lo sa e desidera impararlo, è ancora più una questione di Google. –

+0

Non si tratta di una risposta semplice, ma se pubblicarla qui significa semplicemente copiarla da qualche altra parte. Questo è ridondante. Mi sembra che alcune persone stiano davvero usando SO per uccidere il tempo libero. Forse sono un po 'di parte, ma mi piace SO per i puzzle e non per le domande simili a una chat. – Caffeine

risposta

52

& è binario and. Se si dispone di un valore binario e si and con un altro valore binario, il risultato sarà il bit a bit and dei due. Un esempio:

01101010 
& 01011001 
= 01001000 

Il bit più a destra è un 1 (e in tal caso il numero è un numero dispari) oppure è 0, nel qual caso il numero è pari. Se si usa il numero & con 1, si guarda solo il bit meno significativo, e il se controlla se il numero è un 1 o uno 0. Come altri hanno menzionato, guarda gli operatori bit a bit per informazioni su come funzionano.

18

Questo è anche interessante conoscere bit e 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

Questa risposta non spiega veramente come && è diverso da & molto bene secondo me. & & lancia entrambi i parametri su boolean, ed è come confrontare un singolo bit. & confronta in modo bit per bit: ogni bit in un parametro viene confrontato con ciascun bit nell'altro. – thomasrutter

+3

"regolare" è noto come logico e/o –

+1

È anche importante sapere che gli operatori bit a bit come & e | operare su interi. Gli esempi in questa risposta funzionano solo perché 'true' converte in' 1' e 'false' converte in' 0'. Se tu avessi 'echo (" cheese "& 4)' produrrebbe zero, mentre 'echo (" cheese "&& 4)' risulterebbe veritiero. – thomasrutter

24

Due operazioni che sono fondamentali per sistemi binari sono OR e AND.

O significa "se A è acceso o B è acceso". Un esempio del mondo reale sarebbe due switch in parallelo. Se entrambi consentono il passaggio di corrente, passa la corrente.

AND significa "se entrambi A e B sono attivi". L'esempio del mondo reale è costituito da due interruttori in serie. La corrente passerà solo se entrambi consentono il passaggio di corrente.

In un computer, questi non sono interruttori fisici ma semiconduttori e la loro funzionalità è denominata logic gates. Fanno lo stesso tipo di cose come gli interruttori - reagiscono alla corrente o alla mancanza di corrente.

Se applicato a numeri interi, ogni bit in un numero viene combinato con ogni bit nell'altro numero. Quindi per capire gli operatori bit a bit OR e AND, è necessario convertire i numeri in binario, quindi eseguire l'operazione OR o AND su ogni coppia di bit corrispondenti.

Ecco perché:

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

Mentre

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

L'(& 1) il funzionamento confronta dunque il più a destra bit a 1 con logica AND. Tutti gli altri bit vengono effettivamente ignorati perché nulla E niente è nulla. Un numero pari in binario è anche un numero pari in notazione decimale (10 è un multiplo di 2).

Altre operazioni fondamentali per i sistemi binari includono NOT e XOR. NON significa 'se A è spento' ed è l'unica forma di porta logica che richiede solo un segnale o 'parametro' invece di due. XOR significa 'se A o B è attivo, ma non entrambi'. E poi ci sono NAND, NOR e NXOR, che sostanzialmente NON sono combinati con AND, OR e XOR, cioè NAND significa 'se A e B sono non entrambi su'.

In programmazione, l'operatore

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

Gli altri possono essere costituiti dalla combinazione di questi, ad esempio:

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

PHP nota specifica

Bitwise operatori non funzionano su valori a virgola mobile e in PHP i valori float verranno convertiti implicitamente in numeri interi per primi. I numeri al di fuori dell'intervallo che possono essere espressi come numeri interi verranno troncati a zero, ovvero tutti i numeri su PHP_INT_MAX avranno un aspetto "pari" nell'espressione ($num & 1)). Se vuoi supportare numeri al di fuori di PHP_INT_MIN/PHP_INT_MAX, avrai bisogno di fmod($num, 2). Se, invece, sei in PHP a 64 bit, i tuoi interi avranno una precisione maggiore rispetto ai float.

+2

Personalmente ritengo che questo spieghi meglio il problema della risposta accettata, in quanto spiega in realtà quali operazioni di bit-through fanno dietro le quinte, che è ** cruciale ** per comprenderle e usarle. – Byson

11

So che la tua domanda riguarda la comprensione dell'operatore bit a bit e la risposta accettata lo spiega bene. Ma per l'esempio che danno, non posso fare a meno di raccomandando si utilizza l'operatore modulo, invece:

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

Perché rende l'intento chiaro che si sta verificando che il numero è dispari (non divisibile per due), e è più generico, in modo da poter utilizzare ($ var% 3) allo stesso modo e dedurre come funziona per qualsiasi N.

11

In aggiunta alle altre risposte, vale la pena notare che

if(func1() && func2()) 

solo Will chiama func2() se func1() restituisce true ("la valutazione zy "), mentre

if(func1() & func2()) 

chiamerà entrambe le funzioni a prescindere, ma le tabelle di verità per entrambi saranno lo stesso (ammesso che ritornano booleani).


thomasrutter indica (nei commenti sotto) che probabilmente non si dovrebbe fare quest'ultimo in pratica. (A & B) non avrà necessariamente la stessa veridicità di (A && B), in particolare quando A e B sono numeri interi. ad es., se A = 1 e B = 2 (entrambi veritieri), A & B sarà falso, mentre A & & B è sincero. Inoltre, un altro sviluppatore potrebbe pensare che sia un refuso e "corretto" su due e commerciali.

+1

+1, questo è molto interessante e sconosciuto a tutti – dgraziotin

+0

Importante distinzione. –

+1

Mentre questo * funziona * la maggior parte del tempo *, non funzionerà sempre, come quando le funzioni restituiscono numeri. Diciamo che func1() restituisce 1 e func2() restituisce 4. 'func1() && func2()' valuterà a 'true' mentre' func1() & func2() 'valuterà a' 0'. Anche nei casi in cui funziona, non lo definirei una buona pratica di codifica poiché si basa sugli effetti collaterali dell'ordine di valutazione e sulla conversione dei tipi, rendendo più difficile leggere e comprendere lo scopo del codice. Qualsiasi persona che rivede il codice potrebbe presumere che si tratti di un refuso. – thomasrutter