Was sind einige reale Anwendungsfälle der folgenden bitweisen Operatoren?
- UND
- XOR
- NICHT
- ODER
- Links- / Rechtsverschiebung
language-agnostic
bitwise-operators
Louis Go
quelle
quelle
Antworten:
Bitfelder (Flags)
Sie sind die effizienteste Art, etwas darzustellen, dessen Status durch mehrere "Ja oder Nein" -Eigenschaften definiert ist. ACLs sind ein gutes Beispiel. Wenn Sie beispielsweise 4 diskrete Berechtigungen (Lesen, Schreiben, Ausführen, Ändern von Richtlinien) haben, ist es besser, diese in 1 Byte zu speichern, als 4 zu verschwenden. Diese können für zusätzlichen Komfort Aufzählungstypen in vielen Sprachen zugeordnet werden.
Die Kommunikation über Ports / Sockets
umfasst immer Prüfsummen, Parität, Stoppbits, Flusssteuerungsalgorithmen usw., die normalerweise von den Logikwerten einzelner Bytes im Gegensatz zu numerischen Werten abhängen, da das Medium möglicherweise nur ein Bit übertragen kann eine Zeit.
Komprimierung, Verschlüsselung
Beide sind stark von bitweisen Algorithmen abhängig. Schauen Sie sich den Deflate- Algorithmus als Beispiel an - alles ist in Bits, nicht in Bytes.
Finite-State-Maschinen
Ich spreche hauptsächlich von der Art, die in eine Hardware eingebettet ist, obwohl sie auch in Software zu finden sind. Dies sind die kombinatorischen in der Natur - sie könnten buchstäblich bekommen „kompilierte“ bis zu einer Reihe von Logikgattern, so dass sie wie folgt ausgedrückt werden
AND
,OR
,NOT
usw.Grafik Hier ist kaum genug Platz, um in jeden Bereich zu gelangen, in dem diese Operatoren in der Grafikprogrammierung verwendet werden.
XOR
(oder^
) ist hier besonders interessant, da ein zweites Anwenden derselben Eingabe die erste rückgängig macht. Ältere GUIs stützten sich bei der Hervorhebung der Auswahl und anderen Überlagerungen darauf, um kostspielige Neuzeichnungen zu vermeiden. Sie sind immer noch nützlich in langsamen Grafikprotokollen (dh Remotedesktop).Dies waren nur die ersten Beispiele, die ich mir ausgedacht habe - dies ist kaum eine vollständige Liste.
quelle
Ist es seltsam?
Ist es durch zwei (gerade) teilbar?
quelle
Hier sind einige gebräuchliche Redewendungen, die sich mit Flags befassen, die als einzelne Bits gespeichert sind.
Setzen Sie das Flag Chargeable:
CallerIDMissing-Flag löschen:
Testen Sie, ob CallerIDMissing und Chargeable eingestellt sind:
quelle
Ich habe bei der Implementierung eines Sicherheitsmodells für ein CMS bitweise Operationen verwendet. Es gab Seiten, auf die Benutzer zugreifen konnten, wenn sie sich in geeigneten Gruppen befanden. Ein Benutzer kann sich in mehreren Gruppen befinden, daher mussten wir überprüfen, ob es einen Schnittpunkt zwischen den Benutzergruppen und den Seitengruppen gab. Deshalb haben wir jeder Gruppe eine eindeutige Potenz-2-Kennung zugewiesen, z.
Wir ODER diese Werte zusammen und speichern den Wert (als einzelnes int) mit der Seite. Wenn beispielsweise die Gruppen A und B auf eine Seite zugreifen können, speichern wir den Wert 3 (der binär 00000011 ist) als Seitenzugriffskontrolle. In ähnlicher Weise speichern wir einen Wert von ORed-Gruppen-IDs mit einem Benutzer, um darzustellen, in welchen Gruppen sie sich befinden.
Um zu überprüfen, ob ein bestimmter Benutzer auf eine bestimmte Seite zugreifen kann, müssen Sie nur die Werte UND-Werte zusammen UND prüfen, ob der Wert nicht Null ist. Dies ist sehr schnell, da diese Prüfung in einem einzigen Befehl implementiert wird, keine Schleifen, keine Datenbank-Roundtrips.
quelle
Low-Level-Programmierung ist ein gutes Beispiel. Möglicherweise müssen Sie beispielsweise ein bestimmtes Bit in ein Speicherregister schreiben, damit eine Hardware das tut, was Sie möchten:
Auch
htonl()
undhtons()
ist die Verwendung implementiert&
und|
Operatoren (bei Maschinen , dessen endianness (Byte - Reihenfolge) kein Netzwerk übereinstimmen , um):quelle
htons()
undhtonl()
sind POSIX-Funktionen zum Austauschen von ashort
oder along
von der host (h
) -Endianness in die network (n
) - Bytereihenfolge.htonl()
für einen 32-Bit-int
Wert?long
bedeutet 64-Bit in vielen Sprachen.Ich benutze sie zum Beispiel, um RGB (A) -Werte aus gepackten Farbwerten zu erhalten.
quelle
(a & b) >> c
ist es mehr als fünfmal schneller alsa % d / e
(beide Möglichkeiten, einen einzelnen Farbwert aus einem Int zu extrahieren, das ARGB darstellt). Jeweils 6,7 s und 35,2 s für 1 Milliarde Iterationen.%
nicht der Moduloperator, sondern der Restoperator ist. Sie sind für positive Werte äquivalent, unterscheiden sich jedoch von negativen. Wenn Sie die entsprechenden Einschränkungen vorsehen (vorbei an eineruint
Stelle vonint
zum Beispiel) , dann die beiden Beispiele sollen die gleiche Geschwindigkeit.Wenn ich ein paar boolesche Flags habe, speichere ich sie alle gerne in einem int.
Ich hole sie mit bitweisem UND raus. Beispielsweise:
etc.
quelle
if (flags.feature_one_is_one) { // turn on feature }
. Es ist im ANSI C-Standard enthalten, daher sollte Portabilität kein Problem sein.& = AND:
Maskiert bestimmte Bits.
Sie definieren die spezifischen Bits, die angezeigt oder nicht angezeigt werden sollen. 0x0 & x löscht alle Bits in einem Byte, während 0xFF x nicht ändert. 0x0F zeigt die Bits im unteren Halbbyte an.
Konvertierung:
Um kürzere Variablen in längere mit Bitidentität umzuwandeln, müssen die Bits angepasst werden, da -1 in einem int 0xFFFFFFFF ist, während -1 in einem langen 0xFFFFFFFFFFFFFFFF ist. Um die Identität zu erhalten, wenden Sie nach der Konvertierung eine Maske an.
| = ODER
Bits setzen. Die Bits werden unabhängig gesetzt, wenn sie bereits gesetzt sind. Viele Datenstrukturen (Bitfelder) haben Flags wie IS_HSET = 0, IS_VSET = 1, die unabhängig gesetzt werden können. Um die Flags zu setzen, wenden Sie IS_HSET | an IS_VSET (In C und Assembly ist dies sehr bequem zu lesen)
^ = XOR
Finde gleiche oder unterschiedliche Bits.
~ = NICHT
Bits spiegeln.
Es kann gezeigt werden, dass alle möglichen lokalen Bitoperationen durch diese Operationen implementiert werden können. Wenn Sie möchten, können Sie einen ADD-Befehl ausschließlich durch Bitoperationen implementieren.
Einige wundervolle Hacks:
http://www.ugcs.caltech.edu/~wnoise/base2.html
http://www.jjj.de/bitwizardry/bitwizardrypage.html
quelle
= ~
, nicht|=
, was ODER ist.& = AND
- Warum sollte ich alle Bits löschen wollen, warum sollte ich eine unveränderte Version des Bytes erhalten wollen und was soll ich mit dem unteren Halbbyte tun?xor
es für sich. Ich kann mir einige Gründe vorstellen, warum Sie das untere Knabberzeug extrahieren möchten. Insbesondere, wenn dieses untere Halbbyte Teil einer Datenstruktur ist und Sie es als Maske oderOR
mit einer anderen Struktur verwenden möchten .Verschlüsselung ist alles bitweise Operationen.
quelle
Sie können sie als schnelle und schmutzige Methode zum Hashing von Daten verwenden.
quelle
Ich habe gerade vor
^
ungefähr drei Minuten bitwise-XOR ( ) verwendet, um eine Prüfsumme für die serielle Kommunikation mit einer SPS zu berechnen ...quelle
Bitweise & wird verwendet, um einen bestimmten Teil eines Bytes zu maskieren / zu extrahieren.
1 Byte Variable
Insbesondere der Schichtoperator (<< >>) wird häufig für Berechnungen verwendet.
quelle
Dies ist ein Beispiel zum Lesen von Farben aus einem Bitmap-Bild im Byte-Format
Ich hoffe dieses winzige Beispiel hilft ....
quelle
In der abstrahierten Welt der heutigen modernen Sprache nicht zu viele. Datei-E / A ist eine einfache Aufgabe, die in den Sinn kommt, obwohl sie bitweise Operationen an bereits implementierten Objekten ausführt und keine bitweisen Operationen implementiert. Als einfaches Beispiel zeigt dieser Code das Entfernen des schreibgeschützten Attributs für eine Datei (damit es mit einem neuen FileStream verwendet werden kann, der FileMode.Create angibt) in c #:
In Bezug auf benutzerdefinierte Implementierungen ist hier ein aktuelles Beispiel: Ich habe ein "Message Center" zum Senden sicherer Nachrichten von einer Installation unserer verteilten Anwendung an eine andere erstellt. Grundsätzlich ist es analog zu E-Mail, einschließlich Posteingang, Postausgang, Gesendet usw., aber es hat auch eine garantierte Zustellung mit Lesebestätigungen, sodass es zusätzliche Unterordner gibt, die über "Posteingang" und "gesendet" hinausgehen. Was dies bedeutete, war für mich eine Anforderung, generisch zu definieren, was "im Posteingang" oder was "im gesendeten Ordner" ist. Von dem gesendeten Ordner muss ich wissen, was gelesen und was ungelesen ist. Von dem, was ungelesen ist, muss ich wissen, was empfangen wurde und was nicht. Ich verwende diese Informationen, um eine dynamische where-Klausel zu erstellen, die eine lokale Datenquelle filtert und die entsprechenden Informationen anzeigt.
So wird die Aufzählung zusammengestellt:
Sehen Sie, was das tut? Durch Anding (&) mit dem Enum-Wert "Inbox", InboundMemos, weiß ich, dass sich InboundMemosForMyOrders im Posteingang befindet.
Hier ist eine überarbeitete Version der Methode, mit der der Filter erstellt und zurückgegeben wird, der eine Ansicht für den aktuell ausgewählten Ordner definiert:
Extrem einfach, aber eine ordentliche Implementierung auf einer Abstraktionsebene, die normalerweise keine bitweisen Operationen erfordert.
quelle
Die Base64-Codierung ist ein Beispiel. Die Base64-Codierung wird verwendet, um Binärdaten als druckbare Zeichen für das Senden über E-Mail-Systeme (und andere Zwecke) darzustellen. Die Base64-Codierung konvertiert eine Reihe von 8-Bit-Bytes in 6-Bit-Zeichensuchindizes. Bitoperationen, Verschieben und "oder", "Noting" sind sehr nützlich, um die für die Base64-Codierung und -Decodierung erforderlichen Bitoperationen zu implementieren.
Dies ist natürlich nur eines von unzähligen Beispielen.
quelle
Ich bin überrascht, dass niemand die offensichtliche Antwort für das Internetzeitalter ausgewählt hat. Berechnung gültiger Netzwerkadressen für ein Subnetz.
http://www.topwebhosts.org/tools/netmask.php
quelle
Normalerweise sind bitweise Operationen schneller als Multiplizieren / Dividieren. Wenn Sie also eine Variable x mit beispielsweise 9 multiplizieren müssen, tun Sie dies,
x<<3 + x
was einige Zyklen schneller wäre alsx*9
. Wenn sich dieser Code in einem ISR befindet, sparen Sie Antwortzeit.Wenn Sie ein Array als kreisförmige Warteschlange verwenden möchten, ist es ebenfalls schneller (und eleganter), Wrap-Around-Prüfungen mit bitweisen Operationen durchzuführen. (Ihre Array-Größe sollte eine Potenz von 2 sein). Beispiel: Sie können
tail = ((tail & MASK) + 1)
anstelle von verwendentail = ((tail +1) < size) ? tail+1 : 0
, wenn Sie einfügen / löschen möchten.Wenn ein Fehlerflag mehrere Fehlercodes zusammenhalten soll, kann jedes Bit einen eigenen Wert enthalten. Sie können es mit jedem einzelnen Fehlercode UND überprüfen. Dies wird in Unix-Fehlercodes verwendet.
Auch eine n-Bit-Bitmap kann eine wirklich coole und kompakte Datenstruktur sein. Wenn Sie einen Ressourcenpool der Größe n zuweisen möchten, können wir n-Bits verwenden, um den aktuellen Status darzustellen.
quelle
Niemand scheint Fixpunktmathematik erwähnt zu haben.
(Ja, ich bin alt, ok?)
quelle
Ist eine Zahl
x
eine Potenz von 2? (Nützlich zum Beispiel bei Algorithmen, bei denen ein Zähler inkrementiert wird und eine Aktion nur logarithmisch ausgeführt werden soll.)Welches ist das höchste Bit einer ganzen Zahl
x
? (Dies kann zum Beispiel verwendet werden, um die Mindestleistung von 2 zu ermitteln, die größer ist alsx
)Welches ist das niedrigste
1
Bit einer ganzen Zahlx
? (Hilft zu finden, wie oft durch 2 teilbar ist.)quelle
x & -x
.Bitweise Operatoren sind nützlich, um Arrays zu schleifen, deren Länge die Potenz von 2 ist. Wie viele Leute erwähnt haben, sind bitweise Operatoren äußerst nützlich und werden in Flags , Grafiken , Netzwerken und Verschlüsselung verwendet . Nicht nur das, sie sind auch extrem schnell. Mein persönlicher Lieblingsgebrauch ist das Schleifen eines Arrays ohne Bedingungen . Angenommen, Sie haben ein Array mit null Index (z. B. der Index des ersten Elements ist 0) und müssen es auf unbestimmte Zeit durchlaufen. Mit auf unbestimmte Zeit meine ich, vom ersten zum letzten Element zu gehen und zum ersten zurückzukehren. Eine Möglichkeit, dies zu implementieren, ist:
Dies ist der einfachste Ansatz. Wenn Sie die if- Anweisung vermeiden möchten, können Sie den Modul- Ansatz folgendermaßen verwenden:
Der Nachteil dieser beiden Methoden ist, dass der Moduloperator teuer ist, da er nach einer ganzzahligen Division nach einem Rest sucht. Die erste Methode führt bei jeder Iteration eine if- Anweisung aus. Mit dem bitweisen Operator können Sie jedoch, wenn die Länge Ihres Arrays eine Potenz von 2 ist, einfach eine Sequenz wie diese generieren,
0 .. length - 1
indem Sie den&
(bitweisen und) Operator wie folgt verwendeni & length
. Wenn Sie dies wissen, wird der Code von obenSo funktioniert es. Im Binärformat wird jede Zahl, deren Potenz von 2 von 1 subtrahiert wird, nur mit Einsen ausgedrückt. Zum Beispiel ist 3 in binär
11
, 7 ist111
, 15 ist1111
und so weiter, Sie bekommen die Idee. Was passiert nun, wenn Sie&
eine Zahl gegen eine Zahl haben, die nur aus Einsen in Binärform besteht? Nehmen wir an, wir machen das:Wenn
num
kleiner oder gleich 7 ist, ist das Ergebnis,num
dass jedes Bit&
mit 1 selbst ist. Wennnum
größer als 7 ist,&
berücksichtigt der Computer während des Betriebs die führenden Nullen von 7, die natürlich nach dem&
Betrieb als Nullen bleiben, nur der nachfolgende Teil bleibt übrig. Wie im Fall von9 & 7
in binär wird es so aussehenDas Ergebnis ist 0001, was 1 in Dezimalzahl ist und das zweite Element im Array adressiert.
quelle
Ich verwende sie für Mehrfachauswahloptionen. Auf diese Weise speichere ich nur einen Wert anstelle von 10 oder mehr
quelle
Es kann auch in einem relationalen SQL-Modell nützlich sein. Angenommen, Sie haben die folgenden Tabellen: BlogEntry, BlogCategory
Traditionell können Sie mithilfe einer BlogEntryCategory-Tabelle eine nn-Beziehung zwischen ihnen erstellen. Wenn nicht so viele BlogCategory-Datensätze vorhanden sind, können Sie einen Wert in BlogEntry verwenden, um eine Verknüpfung mit mehreren BlogCategory-Datensätzen herzustellen, genau wie bei gekennzeichneten Aufzählungen. In den meisten RDBMS gibt es diese Ein sehr schneller Operator, der in dieser 'markierten' Spalte ausgewählt werden kann ...
quelle
Wenn Sie nur einige Bits der Ausgänge eines Mikrocontrollers ändern möchten, das zu schreibende Register jedoch ein Byte ist, gehen Sie wie folgt vor (Pseudocode):
Natürlich können Sie bei vielen Mikrocontrollern jedes Bit einzeln ändern ...
quelle
Wenn Sie jemals Ihre Zahl mod (%) mit einer bestimmten Potenz von 2 berechnen möchten, können Sie diese verwenden
yourNumber & 2^N-1
, was in diesem Fall dasselbe ist wieyourNumber % 2^N
.Dies ist wahrscheinlich nur eine Alternative zum Modulbetrieb mit einer sehr großen Dividende von 2 ^ N ... Aber selbst dann ist seine Geschwindigkeitssteigerung gegenüber dem Modulbetrieb in meinem Test unter .NET 2.0 vernachlässigbar. Ich vermute, dass moderne Compiler solche Optimierungen bereits durchführen. Weiß jemand mehr darüber?
quelle
%
bei der Restoperation werden Negative unterschiedlich behandelt. Wenn Sie jedochuint
an übergeben%
, erzeugt der C # -Compiler tatsächlich Maschinencode mit bitweisem UND, wenn das zweite Argument eine vorbekannte Zweierpotenz ist.Ich habe gesehen, dass sie in rollenbasierten Zugriffskontrollsystemen verwendet werden.
quelle
In meiner Frage gibt es hier eine reale Verwendung -
Nur auf die erste WM_KEYDOWN-Benachrichtigung antworten?
Beim Konsumieren einer WM_KEYDOWN-Nachricht im Windows-API-Bit 30 wird der vorherige Schlüsselstatus angegeben. Der Wert ist 1, wenn der Schlüssel gedrückt ist, bevor die Nachricht gesendet wird, oder Null, wenn der Schlüssel oben ist
quelle
Sie werden meist für bitweise Operationen verwendet (Überraschung). Hier sind einige Beispiele aus der Praxis in der PHP-Codebasis.
Zeichenkodierung:
Datenstrukturen:
Datenbanktreiber:
Compiler-Implementierung:
quelle
Wann immer ich mit der C-Programmierung anfing, verstand ich die Wahrheitstabellen und all das, aber es klickte nicht alles darauf, wie man sie tatsächlich verwendet, bis ich diesen Artikel http://www.gamedev.net/reference/articles/article1563.asp las (was Beispiele aus dem wirklichen Leben gibt)
quelle
x == 1
undy == 2
dannx || y
1 undx | y
0. Ich sehe auch nicht, warumx^true
es!x
in irgendeiner Weise überlegen ist . Es ist mehr tippen, weniger idiomatisch, und wennx
es nicht so ist, istbool
es unzuverlässig.x^true
überlegen ist,!x
ist, dasssome->complicated().member->lookup ^= true;
es keine zusammengesetzten Zuweisungsversionen von unären Operatoren gibt.Ich denke nicht, dass dies bitweise zählt, aber Rubys Array definiert Set-Operationen durch die normalen ganzzahligen bitweisen Operatoren. Also
[1,2,4] & [1,2,3] # => [1,2]
. Ähnliches gilt füra ^ b #=> set difference
unda | b #=> union
.quelle
Die lineare Lösung von Tower Of Hanoi verwendet bitweise Operationen, um das Problem zu lösen.
Die Erklärung für diese Lösung finden Sie hier
quelle