Ich bin auf das folgende Code-Snippet gestoßen
if( 0 != ( x ^ 0x1 ) )
encode( x, m );
Was heißt x ^ 0x1
das Ist das eine Standardtechnik?
c++
c
bit-manipulation
bitmask
KodeWarrior
quelle
quelle
0 != (x ^ 1)
→ xoder beide Seiten um 1 →(0 ^ 1) != (x ^ 1 ^ 1)
→ vereinfachen →1 != x
if (1 != x)
schwer es ist zu schreiben.type
ofx
nicht angegeben ist - daher wissen wir nicht, dass dies eine Ganzzahl in diesem C ++ - Tag-Problem ist. Sicher, wenn dies C oderx
eine ganze Zahl ist, ist die Antwort einfach, aber das ist nicht gegeben und die Möglichkeit einer Überladungoperator ^
besteht.Antworten:
Die XOR-Operation (
x ^ 0x1
) invertiert Bit 0. Der Ausdruck bedeutet also effektiv: Wenn Bit 0 von x 0 ist oder ein anderes Bit von x 1 ist, ist der Ausdruck wahr.Umgekehrt ist der Ausdruck falsch, wenn x == 1 ist.
Der Test ist also der gleiche wie:
und ist daher (wohl) unnötig verschleiert.
quelle
^
ist die bitweise XOR- Operation0x1
ist1
in hexadezimaler Schreibweisex ^ 0x1
wird das letzte Bit von invertierenx
(siehe die XOR-Wahrheitstabelle im obigen Link, wenn Ihnen das nicht klar ist).Also der Zustand
(0 != ( x ^ 0x1 ))
ist also wahr, wenn siex
größer als 1 ist oder wenn das letzte Bit vonx
0 ist. Dadurch bleibt nur x == 1 als Wert übrig, bei dem die Bedingung falsch ist. Es ist also gleichbedeutend mitPS Eine verdammt gute Möglichkeit, eine so einfache Bedingung zu implementieren, könnte ich hinzufügen. Tu das nicht. Und wenn Sie komplizierten Code schreiben müssen, hinterlassen Sie einen Kommentar . Ich bitte dich.
quelle
x==0
;4 ^ 0x1
ist wahr, aber4==0
offensichtlich falsch.if (x == 0)
", ist es nicht gleichx != 1
?x
es sich um einen integralen Typ handelt. Wenn es einfloat
oder istdouble
, dann glaube ich, dass der Ausdruck wahr sein würde1.0 <= x < 2.0
. Und wennx
es sich um einen benutzerdefinierten Typ handelt, könnte der Ausdruck true zurückgeben, wennx
es sich um einen Yugo, ein Känguru, einen Geburtstag eines berühmten Komponisten oder eine beliebige Zahl handelt, die mindestens drei Ziffern mit dem aktuellen Dollar-Preis für Tee in China teilt.operator^
fürfloat
/double
.Dies mag als vereinfachte Erklärung erscheinen, aber wenn jemand es langsam durchgehen möchte, ist es unten:
^
ist ein bitweiser XOR- Operator in c, c ++ und c #.Die Wahrheitstabelle von a xor b :
Lassen Sie uns den
0 == ( x ^ 0x1 )
Ausdruck auf Binärebene veranschaulichen :so:
quelle
Es ist exklusiver OR (XOR) -Operator. Um zu verstehen, wie es funktioniert, können Sie diesen einfachen Code ausführen
Die Ausgabe wird sein
Also dieser Ausdruck
wird nur dann gleich wahr sein, wenn x! = 0x1.
Es ändert x selbst nicht. Es wird nur geprüft, ob x gleich 0 oder 1 ist. Dieser Ausdruck kann in geändert werden
quelle
Es überprüft, ob
x
tatsächlich nicht0x1
...xor
ingx
mit0x1
nur 0 führen, wennx
ist0x1
... das ist ein alter Trick meist in Assemblersprache verwendetquelle
!= 1
?xor
enthielt der Ansatz bei manuellen Baugruppenoptimierungen (x86), wenn ich mich richtig erinnere, weniger Maschinencode und wurde schneller ausgeführt als die entsprechende Zuordnung zu0
... Diese Frage enthält jedoch einxor
UND-Vergleich, sodass ich vielleicht denke, dass dies der!=
Fall sein könnte schneller. Ich bin mir jedoch nicht sicher, ob ich eine vom Compiler generierte Assembly sehen müsste.Der
^
Operator ist bitweise xor. Und0x1
ist die Zahl1
, geschrieben als hexadezimale Konstante.So
x ^ 0x1
wertet auf einen neuen Wert, der die gleiche ist wiex
, aber mit dem niedrigstwertigen Bit umgedreht.Der Code vergleicht x nur mit 1 auf sehr verworrene und dunkle Weise.
quelle
Der xor-Operator (exklusiv oder) wird am häufigsten verwendet, um ein oder mehrere Bits zu invertieren. Die Operation besteht darin, zu fragen, ob genau eines der Bits eins ist. Dies führt zu der folgenden Wahrheitstabelle (A und B sind Eingaben, Y ist Ausgaben):
Nun scheint der Zweck dieses Codes zu sein, zu überprüfen, ob genau das letzte Bit 1 ist und die anderen 0 sind, dies ist gleich
if ( x != 1 )
. Der Grund für diese obskure Methode könnte sein, dass frühere Bitmanipulationstechniken verwendet wurden und möglicherweise an anderen Stellen im Programm verwendet werden.quelle
^
ist bitweisexor operator
inc
. In Ihrem Fall ist x mit 1 xor'ed. Hat beispielsweisex
den Wert 10, dann wird die10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d
Bedingung wahr.quelle
10 != 1010
10 (decimal) == 1010 (binary)
b
oder etwas einfügen ?Der bitweise Test scheint eine absichtliche Verschleierung zu sein. Wenn es sich bei den zugrunde liegenden Daten jedoch um Unternehmensdaten eines IBM Mainframe-Systems handelt, kann es einfach sein, dass der Code so geschrieben wurde, dass er die Originaldokumentation widerspiegelt. IBM Datenformate reichen bis in die 1960er Jahre zurück und codieren Flags häufig als einzelne Bits innerhalb eines Wortes, um Speicherplatz zu sparen. Während die Formate geändert wurden, wurden Flag-Bytes am Ende der vorhandenen Datensätze hinzugefügt, um die Abwärtskompatibilität aufrechtzuerhalten. In der Dokumentation für einen SMF-Datensatz wird beispielsweise möglicherweise der Assembler-Code angezeigt, mit dem drei einzelne Bits innerhalb von drei verschiedenen Wörtern in einem einzelnen Datensatz getestet werden können, um zu entscheiden, dass es sich bei den Daten um eine Eingabedatei handelt. Ich weiß viel weniger über TCP / IP-Interna, aber dort finden Sie möglicherweise auch Bit-Flags.
quelle
Der Operator ^ ist das bitweise xor (siehe &, |). Das Ergebnis für ein Bitpaar ist:
Also der Ausdruck,
invertiert / kippt das 0. Bit von x (wobei andere Bits unverändert bleiben).
Überlegen Sie, ob x neben 0x0 und 0x1 auch andere Werte haben kann? Wenn x ein einzelnes Bitfeld ist, kann es nur die Werte 0x0 und 0x1 haben. Wenn x jedoch ein int ist (char / short / long / etc), können Bits neben bit0 das Ergebnis des Ausdrucks beeinflussen.
Der angegebene Ausdruck ermöglicht es Bits neben Bit0, das Ergebnis zu beeinflussen.
Welches hat die gleiche Wahrhaftigkeit wie dieser (einfachere) Ausdruck,
Beachten Sie, dass dieser Ausdruck nur Bit0 untersuchen würde.
Der dargestellte Ausdruck kombiniert also wirklich zwei Ausdrucksprüfungen.
Wollte der Autor nur Bit0 überprüfen und wollte diesen Ausdruck verwenden?
Oder hatte der Autor vor, die Werte für Bit1-BitN und das Xor von Bit0 zu ermitteln?
quelle
Ich füge eine neue Antwort hinzu, weil niemand wirklich erklärt hat, wie man die Antwort intuitiv erhält.
Die Umkehrung von
+
ist-
.Die Umkehrung von
^
ist^
.Wie Sie lösen
0 != x - 1
fürx
? Sie+ 1
zu beiden Seiten:0 + 1 != x - 1 + 1
→1 != x
.Wie Sie lösen
0 != x ^ 1
fürx
? Sie^ 1
zu beiden Seiten:0 ^ 1 != x ^ 1 ^ 1
→1 != x
.quelle
Ich würde vermuten, dass es andere Bits oder Bitfeldwerte gibt
x
, und dies soll testen, ob nur das niederwertige Bit gesetzt ist. Im Zusammenhang würde ich vermuten, dass dies die Standardeinstellung ist und daher die Codierung dieser und einiger verwandter Elementem
(wahrscheinlich teurer zu codierender) Elemente übersprungen werden kann, da beide der Standardwert sein müssen, der in einem Konstruktor oder ähnlichem initialisiert wurde.Irgendwie muss der Decoder in der Lage sein zu schließen, dass diese Werte fehlen. Wenn sie sich am Ende einer Struktur befinden, kann dies über einen
length
Wert erfolgen, der immer vorhanden ist.quelle
Das XOR ist in der C # -Flag-Aufzählung nützlich. Um ein einzelnes Flag aus dem Enum-Wert zu entfernen, muss der Operator xor verwendet werden (siehe hier) ).
Beispiel:
quelle
Es gibt viele gute Antworten, aber ich denke gerne einfacher darüber nach.
Zuerst. Eine if-Anweisung ist nur falsch, wenn das Argument Null ist. Dies bedeutet, dass ein Vergleich ungleich Null sinnlos ist.
Das lässt uns also mit:
Ein XOR mit einem. Was für ein XOR tut , ist im Wesentlichen erkennen Bits , die unterschiedlich sind. Wenn also alle Bits gleich sind, wird 0 zurückgegeben. Da 0 falsch ist, wird nur dann false zurückgegeben, wenn alle Bits gleich sind. Es ist also falsch, wenn die Argumente gleich sind, wahr, wenn sie unterschiedlich sind ... genau wie der Operator ungleich .
Tatsächlich besteht der einzige Unterschied zwischen den beiden darin, dass
!=
0 oder 1 zurückgegeben wird, während^
eine beliebige Zahl zurückgegeben wird, die Wahrhaftigkeit des Ergebnisses jedoch immer dieselbe ist. Eine einfache Möglichkeit, darüber nachzudenken, ist.Die letzte "Vereinfachung" ist die Konvertierung
0x1
in eine Dezimalzahl von 1. Daher entspricht Ihre Aussage:quelle
^ ist ein bitweiser XOR- Operator
Wenn x = 1
hier 0 == (x ^ 0x1)
Wenn x = 0
hier 0! = (x ^ 0x1)
Die Wahrheitstabelle von a xor b:
Der Code bedeutet einfach
quelle
Die Standardtechnik, die hier verwendet werden könnte, besteht darin, ein Idiom, wie es im umgebenden Kontext erscheint, aus Gründen der Klarheit zu wiederholen, anstatt es zu verschleiern, indem es durch ein Idiom ersetzt wird, das arithmetisch einfacher, aber kontextuell bedeutungslos ist.
Der umgebende Code kann häufig auf verweisen
(x ^ 1)
, oder der Test fragt möglicherweise: "Wenn Bit 0 umgekehrt wäre, wäre diese Bitmaske leer?".Angesichts der Tatsache, dass die Bedingung dazu führt, dass etwas
encode()
bearbeitet wird, kann es sein, dass im Kontext der Standardzustand von Bit 0 durch andere Faktoren invertiert wurde und wir zusätzliche Informationen nur dann codieren müssen, wenn eines der Bits von ihrem Standard abweicht (normalerweise alle Null) ).Wenn Sie den Ausdruck aus dem Kontext nehmen und fragen, was er bewirkt, übersehen Sie die zugrunde liegende Absicht. Sie können sich auch die Assembly-Ausgabe des Compilers ansehen und feststellen, dass lediglich ein direkter Gleichheitsvergleich mit 1 durchgeführt wird.
quelle
Wie ich die Antworten bisher sehe, fehlt eine einfache Regel für den Umgang mit
XOR
s. Ohne ins Detail zu gehen, was^
und was0x
(undif
, und!=
usw.) bedeutet, kann der Ausdruck0 != (x^1)
wie folgt überarbeitet werden, indem Folgendes verwendet wird(a^a)==0
:quelle