2010-10-02 18 views
49

Sono confuso da quando dovrei usare un valore booleano vs operatori bit a bitoperatori booleani vs operatori bit a bit

and vs &, or vs | 

Qualcuno mi potrebbe illuminare da quando faccio a utilizzare ogni e quando si utilizza uno sopra l'altro influisce sul mio risultati?

+13

Si noti che le risposte avrete si applica approssimativamente a tutte le altre lingue (imperative mainstream). – delnan

risposta

45

Qui ci sono un paio di linee guida:

  • operatori booleani sono di solito utilizzati su booleane valori, ma gli operatori bit per bit sono normalmente utilizzati su intero valori.
  • Gli operatori booleani sono in cortocircuito ma gli operatori bit a bit sono non in cortocircuito.

Il corto circuito comportamento è utile in espressioni come questa:

if x is not None and x.foo == 42: 
    # ... 

Ciò non funzionare correttamente con l'operatore bitwise & perché entrambe le parti sarebbero sempre valutati, dando AttributeError: 'NoneType' object has no attribute 'foo'. Quando si utilizza l'operatore booleano and, la seconda espressione non viene valutata quando il primo è False. Allo stesso modo or non valuta il secondo argomento se il primo è True.

+8

Supplementare: in Python '&', '|', '^' sono anche operazioni impostate. – kennytm

+2

Additional additional: in Python, bit-wise non consentirà tipi misti, ma booleano lo farà. per esempio. 'True o" True "' sta bene (restituirà il primo valore di verità), ma 'True | "True" 'genererà un'eccezione. – Hannele

+4

@Hannele Questo non ha nulla a che fare con i tipi misti. Le operazioni bit a bit hanno senso solo con numeri interi e qualsiasi altro tipo genererà un'eccezione. Il punto qui è che Python tratta False e True come 0 e 1 rispettivamente: '0 == False' e' 1 == True' sono entrambi veri. –

1

Le operazioni booleane sono operazioni logiche.

Le operazioni a bit sono operazioni su bit binari.

operazioni

bit a 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 di operazioni bit per bit:

1) Impostare e cancellare Bits

operazioni booleane:

>>> k = True 
>>> z = False 
>>> k & z # and 
False 
>>> k | z # or 
True 
>>> 
+0

Per le operazioni booleane, non intendi "e" e "o" invece di "&" e "|"? –

+0

Sì .. Sì .. Grazie, intendo davvero. – pyfunc

2

Il suggerimento è nel nome:

  • operatori booleani sono per l'esecuzione di operazioni logiche (verità testare comuni nella programmazione e logica formale)
  • operatori bit a bit sono per "bit-giocherellando" (manipolazione di basso livello di bit in tipi di dati numerici e byte)

Mentre è possibile e infatti a volte desiderabile (tipico per motivi di efficienza) per eseguire operazioni logiche con operatori bit a bit, in genere è necessario evitare tali errori per tali scopi, al fine di prevenire bug sottili e effetti collaterali indesiderati.

Se è necessario modificare i bit, gli operatori bit a bit sono costruiti appositamente.Il libro divertente: Hackers Delight contiene alcuni esempi interessanti e genuini di ciò che può essere ottenuto con il bit-twiddling.

17

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 molte domande qui su come funzionano esattamente queste ultime.

Ecco differenze pratiche che influenzano potenzialmente i risultati:

  1. and e or corto circuito, cioè True or sys.exit(1) non uscirà, perché per un certo valore (True or ..., False and ...) del primo operando, la seconda uno non cambierebbe il risultato = non ha bisogno di essere valutato. Ma | e & non cortocircuiti - True | sys.exit(1) ti butta fuori dal REPL.
  2. (vale solo per alcune lingue con l'overloading degli operatori, tra cui Python :) & e | sono operatori regolari e possono essere sovraccaricato -? and e or sono forgiate nella lingua (anche se almeno in Python, il metodo speciale per la coercizione a boolean può avere effetti collaterali).
  3. (vale solo per alcune lingue [vedi il commento di KennyTM] :) and e or ritorno (sempre? Mai veramente capire questo, né ne ho bisogno) il valore di un operando invece di True o False. Questo non cambia il significato delle espressioni booleane in condizioni - 1 or True è 1, ma anche 1 è vero. Ma una volta veniva utilizzato per emulare un operatore condizionale (cond ? true_val : false_val in sintassi C, true_val if cond else false_val in Python da alcuni anni). Per & e |, il tipo di risultato dipende dal modo in cui gli operandi sovraccaricano i rispettivi metodi speciali (True & False è , 99 & 7 è 3, per insiemi è unioni/intersezione ...).

Ma anche quando ad es. a_boolean & another_boolean funzionerebbe in modo identico, la soluzione giusta sta usando and - semplicemente perché and e or sono associati con l'espressione booleana e le condizioni mentre & e | stand per bit twiddling.

+0

Il punto n. 3 si applica anche a Ruby, Perl e Javascript. Non è specifico di Python. – kennytm

11

Ecco una ulteriore differenza, che mi aveva perplesso per un po 'solo ora: perché & (e gli altri operatori bit per bit) hanno una precedenza maggiore rispetto and (e gli altri operatori booleani) le seguenti espressioni restituiscono valori diversi:

0 < 1 & 0 < 2 

contro

0 < 1 and 0 < 2 

Vale a dire, i primi rese False quanto è equivalente a 0 < (1 & 0) < 2, quindi 0 < 0 < 2, quindi 012.359..

3

Se si sta tentando di eseguire operazioni booleane a livello di elemento in numpy, la risposta è leggermente diversa. È possibile utilizzare & e | per operazioni booleane element-boe, ma and e or restituiranno un errore di valore.

Per sicurezza, è possibile utilizzare numpy logic functions.

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) 
0

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) 
Problemi correlati