Boolesche Operatoren vs Bitweise Operatoren

75

Ich bin verwirrt, wann ich Boolesche vs bitweise Operatoren verwenden soll

  • and vs. &
  • or vs. |

Könnte mich jemand aufklären, wann ich die einzelnen Produkte verwende und wann sich die Verwendung übereinander auf meine Ergebnisse auswirkt?

Jiew Meng
quelle
14
Beachten Sie, dass die Antworten, die Sie erhalten, ungefähr auch für alle anderen (Mainstream-Imperativ-) Sprachen gelten.

Antworten:

74

Hier sind einige Richtlinien:

  • Boolesche Operatoren werden normalerweise für boolesche Werte verwendet, aber bitweise Operatoren werden normalerweise für ganzzahlige Werte verwendet.
  • Boolesche Operatoren schließen kurz, aber bitweise Operatoren schließen nicht kurz.

Das Kurzschlussverhalten ist in folgenden Ausdrücken nützlich:

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

Dies würde mit dem bitweisen &Operator nicht richtig funktionieren, da immer beide Seiten ausgewertet würden AttributeError: 'NoneType' object has no attribute 'foo'. Wenn Sie den booleschen andOperator verwenden, wird der zweite Ausdruck nicht ausgewertet, wenn der erste False ist. In ähnlicher Weise orwird das zweite Argument nicht ausgewertet, wenn das erste True ist.

Mark Byers
quelle
13
Zusatz: In Python &, |, ^werden die Operationen zu setzen.
Kennytm
5
Zusätzliche Ergänzung: In Python werden bitweise keine gemischten Typen zugelassen, boolesche jedoch. zB True or "True"ist in Ordnung (es wird der erste Wahrheitswert zurückgegeben), aber es True | "True"wird eine Ausnahme ausgelöst .
Hannele
7
@Hannele Das hat nichts mit gemischten Typen zu tun. Bitweise Operationen sind nur mit ganzen Zahlen sinnvoll, und jeder andere Typ löst eine Ausnahme aus. Der Punkt hier ist, dass Python False und True als 0 bzw. 1 behandelt: 0 == Falseund 1 == Truebeide wahr sind.
Nuno André
1
@ NunoAndré Richtig, das ist eine genauere Erklärung. Vielen Dank!
Hannele
23

Theoretisch andund orkommen direkt aus der Booleschen Logik (und arbeiten daher mit zwei Booleschen Werten, um einen Booleschen Wert zu erzeugen), während &und |wenden den Booleschen Wert und / oder auf die einzelnen Bits von Ganzzahlen an. Hier gibt es viele Fragen, wie letztere genau funktionieren.

Hier sind praktische Unterschiede, die sich möglicherweise auf Ihre Ergebnisse auswirken:

  1. andund ein orKurzschluss, z. B. True or sys.exit(1)wird nicht beendet, da für einen bestimmten Wert des ersten Operanden ( True or ..., False and ...) der zweite das Ergebnis nicht ändern würde und daher nicht ausgewertet werden muss. Aber |und &nicht kurzschließen - True | sys.exit(1)wirft Sie aus der REPL.
  2. &und |sind reguläre Operatoren und können überladen werden, während andund orin die Sprache gefälscht werden (obwohl die spezielle Methode für Zwang zum Booleschen Wert Nebenwirkungen haben kann).
    • Dies gilt auch für einige andere Sprachen mit Operatorüberladung
  3. andund orgeben Sie den Wert eines Operanden anstelle von Trueoder zurück False. Dies ändert nichts an der Bedeutung von Booleschen Ausdrücken in Bedingungen - 1 or Trueist 1, ist aber auch 1wahr. Es wurde jedoch einmal verwendet, um einen bedingten Operator zu emulieren ( cond ? true_val : false_valin C-Syntax, true_val if cond else false_valin Python). Für &und |hängt das Ergebnis Art, wie die Operanden die jeweiligen speziellen Methoden überlasten ( True & Falseist False, 99 & 7ist 3, für Sätze es Gewerkschaften / Kreuzung ...).
    • Dies gilt auch für einige andere Sprachen wie Ruby, Perl und Javascript

Aber selbst wenn zB a_boolean & another_booleanidentisch funktionieren würde, wird die richtige Lösung verwendet and- einfach weil andund ormit booleschem Ausdruck und Zustand verbunden sind, während &und |für Bit Twiddling stehen.

wjandrea
quelle
21

Hier ist ein weiterer Unterschied, der mich gerade eine Weile verwirrt hat: Weil &(und andere bitweise Operatoren) eine höhere Priorität haben als and(und andere boolesche Operatoren), werden die folgenden Ausdrücke mit unterschiedlichen Werten bewertet:

0 < 1 & 0 < 2

gegen

0 < 1 and 0 < 2

Das erste ergibt also, Falsewie es äquivalent ist 0 < (1 & 0) < 2, daher 0 < 0 < 2daher 0 < 0 and 0 < 2.

Arend
quelle
4

Wenn Sie versuchen, elementweise boolesche Operationen in auszuführen numpy, ist die Antwort etwas anders. Sie können verwenden &und |elementweise Boolesche Operationen für, aber andund orwird Wert Fehler zurück.

Um auf der sicheren Seite zu sein, können Sie die numpy-Logikfunktionen verwenden .

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)
C8H10N4O2
quelle
3

Der Hinweis ist im Namen:

  • Boolesche Operatoren dienen zur Ausführung logischer Operationen (Wahrheitstests, die in der Programmierung und in der formalen Logik üblich sind).
  • Bitweise Operatoren sind für "Bit-Twiddling" (Manipulation von Bits in Byte- und numerischen Datentypen auf niedriger Ebene).

Während es möglich und manchmal wünschenswert ist (normalerweise aus Effizienzgründen), logische Operationen mit bitweisen Operatoren auszuführen, sollten Sie diese für solche Zwecke generell vermeiden, um subtile Fehler und unerwünschte Nebenwirkungen zu vermeiden.

Wenn Sie Bits bearbeiten müssen, sind die bitweisen Operatoren zweckgebunden. Das lustige Buch: Hackers Delight enthält einige coole und wirklich nützliche Beispiele dafür, was mit Bit-Twiddling erreicht werden kann.

Tendayi Mawushe
quelle
2

Die allgemeine Regel besteht darin, den entsprechenden Operator für die vorhandenen Operanden zu verwenden. Verwenden boolean (logische) Operatoren mit boolean Operanden und bitweise Operatoren mit (größeren) integralen Operanden (Anmerkung: Falsch entsprechen 0 , und Wahre zu 1 ). Das einzige "knifflige" Szenario ist das Anwenden von Booleschen Operatoren auf nicht-Boolesche Operanden.
Nehmen wir ein einfaches Beispiel zu nehmen, wie beschrieben in [SO]: Python - Unterschiede zwischen ‚und‘ und ‚&‘ :
5 & 7 vs 5 and 7 .

Für das bitweise und ( & ) sind die Dinge ziemlich einfach:

5     = 0b101
7     = 0b111
-----------------
5 & 7 = 0b101 = 5

Für die logischen und , hier ist was [Python.Docs]: Boolesche Operationen besagt ( Schwerpunkt liegt bei mir):

(Beachten Sie, dass weder und noch oder den Wert und Typ einschränken, den sie auf False und True zurückgeben , sondern das zuletzt ausgewertete Argument zurückgeben .

Beispiel :

>>> 5 and 7
7
>>> 7 and 5
5

Gleiches gilt natürlich auch für | vs. oder .

CristiFati
quelle
1

Boolesche Operationen sind logische Operationen.

Bitweise Operationen sind Operationen an Binärbits.

Bitweise Operationen:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

Die Operationen:

  • UND &: 1, wenn beide Bits 1 sind, andernfalls 0
  • ODER |: 1, wenn eines der Bits 1 ist, andernfalls 0
  • XOR ^: 1, wenn die Bits unterschiedlich sind, 0, wenn sie gleich sind
  • NICHT ~': Flip jedes Bit

Einige der Verwendungen von bitweisen Operationen:

  1. Bits setzen und löschen

Boolesche Operationen:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 
pyfunc
quelle
1
Meinen Sie für boolesche Operationen nicht "und" und "oder" anstelle von "&" und "|"?
Matthew Rankin
Ja .. Ja .. Danke, das meine ich auch.
Pyfunc
0

Boolean 'und' vs. Bitwise '&':

Pseudocode / Python hat mir geholfen, den Unterschied zwischen diesen zu verstehen:

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)
Geoff Langenderfer
quelle
0

Logische Operationen

werden normalerweise für bedingte Anweisungen verwendet. Zum Beispiel:

if a==2 and b>10:
    # Do something ...

Das heißt, wenn beide Bedingungen ( a==2und b>10) gleichzeitig wahr sind, kann der bedingte Anweisungshauptteil ausgeführt werden.

Bitweise Operationen

werden zur Datenmanipulation und -extraktion verwendet. Wenn Sie beispielsweise die vier LSB (Least Significant Bits) einer Ganzzahl extrahieren möchten, können Sie Folgendes tun:

p & 0xF
Pooria
quelle
Die Frage bezieht sich auf Python, aber es schien, als ob diese Antwort in einer anderen Sprache geschrieben wurde - vielleicht Ruby? Wie auch immer, ich habe es repariert. LMK, wenn ich etwas verpasst habe.
Wjandrea