operatori booleani vs operatori bit per bit
-
27-09-2019 - |
Domanda
Sono confuso da quando dovrei usare booleano vs operatori bit per bit
-
and
vs&
-
or
vs|
Qualcuno mi potrebbe illuminare da quando faccio a utilizzare ogni e quando si utilizza uno sopra l'altro sui miei risultati?
Soluzione
Qui ci sono un paio di linee guida:
- Gli operatori booleani sono di solito utilizzati su booleano valori, ma operatori bit per bit sono di solito utilizzati su numero intero valori.
- Gli operatori booleani sono cortocircuito , ma operatori bit per bit sono non corto circuito.
Il comportamento di corto circuito è utile in espressioni come questa:
if x is not None and x.foo == 42:
# ...
Questo non avrebbe funzionato correttamente con l'operatore bit a bit &
perché entrambe le parti sarebbero sempre essere valutati, dando AttributeError: 'NoneType' object has no attribute 'foo'
. Quando si utilizza il and
operator booleana la seconda espressione non viene valutata quando il primo è falso. Allo stesso modo or
non valuta il secondo argomento se il primo è vero.
Altri suggerimenti
In teoria, and
e or
provengono direttamente dalla logica booleana (e quindi operare su due booleani per produrre un boolean), mentre &
e |
applicare il booleano e / o ai singoli bit di numeri interi. Ci sono un sacco sacco di domande qui su come quest'ultimo lavoro esattamente.
Qui ci sono differenze pratiche che interessano potenzialmente i risultati:
-
and
eor
corto circuito, cioèTrue or sys.exit(1)
non uscirà, perché per un certo valore (True or ...
,False and ...
) del primo operando, la seconda non cambierebbe il risultato = non necessario valutare. Ma|
e&
Non cortocircuito -True | sys.exit(1)
si getta outta REPL .
- (si applica solo ad alcune lingue con l'overloading degli operatori, tra cui Python :)
&
e|
sono operatori regolari e possono essere sovraccaricati -?and
eor
sono forgiate nella lingua (anche se almeno in Python, il metodo speciale per la coercizione a booleana può avere effetti collaterali). - (vale solo per alcune lingue [vedi il commento di KennyTM] :)
and
e ritornoor
(sempre? Non capiscono mai realmente questo, né ho bisogno) il valore di un operando invece diTrue
oFalse
. Questo non cambia il significato di espressioni booleane in condizioni -1 or True
è1
, ma1
è vero, troppo. Ma è stato una volta usato per emulare un operatore condizionale (cond ? true_val : false_val
nella sintassi C,true_val if cond else false_val
in Python da alcuni anni). Per&
e|
, il tipo di risultato dipende da come operandi sovraccaricare i rispettivi metodi speciali (True & False
èFalse
,99 & 7
è3
, per gli insiemi di esso unioni / intersezione ...).
Ma anche quando per esempio a_boolean & another_boolean
avrebbe funzionato in modo identico, la giusta soluzione sta usando and
-. semplicemente perché and
e or
sono associati con l'espressione booleana e la condizione, mentre &
e |
supporto per il bit giocherellando
Ecco una ulteriore differenza, che mi aveva perplesso per un po 'solo ora: perché &
(e gli altri operatori bit per bit) hanno una precedenza più alta rispetto and
(e gli altri operatori booleani) le seguenti espressioni restituiscono valori diversi:
0 < 1 & 0 < 2
vs
0 < 1 and 0 < 2
Vale a dire, i primi rese False
come è equivalente a 0 < (1 & 0) < 2
, quindi 0 < 0 < 2
, quindi 0 < 0 and 0 < 2
.
Se si sta tentando di fare operazioni booleane elemento-saggio in numpy
, la risposta è un po 'diversa. È possibile utilizzare &
e |
per operazioni booleane elemento-saggio, ma and
e or
tornerà errore valore.
Per essere sul sicuro, è possibile utilizzare i funzioni logiche numpy .
np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False, True], dtype=bool)
np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False, True], dtype=bool)
operazione booleana sono operazioni logiche.
operazioni bitwise sono operazioni su bit binari.
operazioni bit per bit:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
Le operazioni:
And & 1 if both bits are 1, 0 otherwise
Or | 1 if either bit is 1
Xor ^ 1 if the bits are different, 0 if they're the same
Not ~ Flip each bit
Alcuni degli usi delle operazioni bit per bit:
1) Impostare e cancellare Bit
operazioni booleane:
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
Il suggerimento è nel nome:
- Gli operatori booleani sono per l'esecuzione di operazioni logiche (verità testare comuni nella programmazione e logica formale)
- operatori bit sono per "bit-giocherellando" (manipolazione basso livello di bit nel byte ei tipi di dati numerici)
Anche se è possibile e anzi talvolta desiderabile (in genere per motivi di efficienza) per eseguire operazioni logiche con gli operatori bit per bit, si dovrebbe in genere li evitare a tali fini per evitare bug sottili e gli effetti collaterali indesiderati.
Se avete bisogno di manipolare i bit, quindi gli operatori bit per bit sono appositamente costruito. Il libro divertente: hacker Delight contiene alcuni interessanti e davvero utili esempi di quello che può essere realizzato con bit-giocherellando.
La regola generale è quella di utilizzare l'operatore appropriato per gli operandi esistenti. Usa booleano operatori (logici) con operandi booleani e operatori bit per bit con (più ampia) operandi integrali (nota: false è equivalente a 0 e True a 1 ). L'unico scenario "difficile" sta applicando gli operatori booleani per operandi non booleani.
Facciamo un semplice esempio, come descritto in [SO]: Python - Differenze tra 'e 'e '&'[duplicato] :.. 5 & 7
vs 5 and 7
Per la bit a bit e ( & ), le cose sono piuttosto semplici:
5 = 0b101 7 = 0b111 ----------------- 5 & 7 = 0b101 = 5
Per la logica e , ecco cosa [Python 3]: operazioni booleane stati ( enfasi è mio):
(nota che né e né o limitare il valore e il tipo tornano a false e < em> true , ma restituire l'ultimo argomento valutato .
Esempio :
>>> 5 and 7 7 >>> 7 and 5 5
Naturalmente, lo stesso vale per il |.. vs o
booleano 'e' contro Bitwise '&':
pseudo-codice / Python ha aiutato a capire la differenza tra questi:
def boolAnd(A, B):
# boolean 'and' returns either A or B
if A == False:
return A
else:
return B
def bitwiseAnd(A , B):
# binary representation (e.g. 9 is '1001', 1 is '0001', etc.)
binA = binary(A)
binB = binary(B)
# perform boolean 'and' on each pair of binaries in (A, B)
# then return the result:
# equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])
# assuming binA and binB are the same length
result = []
for i in range(len(binA)):
compar = boolAnd(binA[i], binB[i])
result.append(compar)
# we want to return a string of 1s and 0s, not a list
return ''.join(result)
Operazioni logiche
di solito vengono utilizzati per le istruzioni condizionali. Ad esempio:
if a==2 and b >10 then
/*Do something...*/
endif
Ciò significa che se entrambe le condizioni ((a == 2) (b> 10)) sono vere allo stesso tempo poi corpo condizionale può essere eseguita.
bit a bit Operazioni
operazioni bitwise può essere utilizzato per la manipolazione dei dati e l'estrazione. Ad esempio, se si desidera estrarre quattro LSB (bit meno significativi) di un numero intero, si può fare questo:
Estrazione:
poo & 0x000F
Masking:
poo | 0xFFF0