c++ - enum - Was bedeutet(x ^ 0x1)!=0?




c++ enum flags (12)

Ich bin auf den folgenden Codeausschnitt gestoßen

if( 0 != ( x ^ 0x1 ) )
     encode( x, m );

Was bedeutet x ^ 0x1 ? Ist das eine Standardtechnik?


Das XOR ist in C # -Flagaufzählung nützlich. Um ein einzelnes Flag vom Enum-Wert zu entfernen, ist es notwendig, den xor-Operator zu verwenden (Referenz here )

Beispiel:

[Flags]
enum FlagTest { None 0x0, Test1 0x1, Test2 0x2, Test3 0x4}

FlagTest test = FlagTest.Test2 | FlagTest.Test3;
Console.WriteLine(test); //Out: FlagTest.Test2 | FlagTest.Test3
test = test ^ FlagTest.Test2;
Console.WriteLine(test); //Out: FlagTest.Test3

Der Operator ^ ist bitweise xor. Und 0x1 ist die Zahl 1 , geschrieben als hexadezimale Konstante.

Also wird x ^ 0x1 zu einem neuen Wert ausgewertet, der gleich ist wie x , aber mit dem am wenigsten signifikanten Bit umgedreht.

Der Code tut nichts anderes, als x mit 1 zu vergleichen, in einer sehr verschlungenen und obskuren Art und Weise.


Der bitweise Test scheint eine absichtliche Verschleierung zu sein, aber wenn die zugrunde liegenden Daten Unternehmensdaten von einem IBM Mainframe-System sind, könnte es einfach sein, dass der Code so geschrieben wurde, dass er die ursprüngliche Dokumentation widerspiegelt. IBM Datenformate gehen zurück in die 1960er Jahre und codieren häufig Flags als einzelne Bits in einem Wort, um Speicher zu sparen. Als die Formate geändert wurden, wurden Flag-Bytes am Ende der vorhandenen Datensätze hinzugefügt, um die Rückwärtskompatibilität aufrechtzuerhalten. Die Dokumentation für einen SMF-Datensatz kann z. B. den Assemblersprachcode anzeigen, um drei einzelne Bits in drei verschiedenen Wörtern in einem einzelnen Datensatz zu testen, um zu entscheiden, dass es sich bei den Daten um eine Eingabedatei handelt. Ich weiß viel weniger über TCP / IP-Interna, aber Sie können dort auch Bit-Flags finden.


Der xor (exklusive oder) Operator 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 wird ausgegeben):

A    B    Y
0    0    0
0    1    1
1    0    1
1    1    0

Nun scheint der Zweck dieses Codes zu sein zu überprüfen, ob excatly 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.


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, dann ist der Ausdruck wahr.

Umgekehrt ist der Ausdruck falsch, wenn x == 1 ist.

Also ist der Test der gleiche wie:

if (x != 1)

und ist daher (unnötigerweise) unnötig verschleiert.


Dies mag als eine vereinfachte Erklärung erscheinen, aber wenn jemand es langsam durchmachen möchte, ist es unten:

^ ist ein bitweiser XOR- Operator in c, c ++ und c #.

Ein bitweises XOR nimmt zwei Bitmuster gleicher Länge und führt die logische Exklusiv-ODER-Operation an jedem Paar entsprechender Bits durch.

Exclusive OR ist eine logische Operation, die true ausgibt, wenn sich beide Eingaben unterscheiden (einer ist wahr, der andere ist falsch).

Die Wahrheitstabelle eines xor b :

a           b        a xor b
----------------------------
1           1           0
1           0           1
0           1           1
0           0           0

Lassen Sie uns also den Ausdruck 0 == ( x ^ 0x1 ) auf Binär-Ebene veranschaulichen:

             what? xxxxxxxx (8 bits)
               xor 00000001 (hex 0x1 or 0x01, decimal 1)    
             gives 00000000
---------------------------
the only answer is 00000001

damit:

   0 == ( x ^ 0x1 )    =>    x == 1
   0 != ( x ^ 0x1 )    =>    x != 1

Es ist Exklusiv-OR (XOR) -Operator. Um zu verstehen, wie es funktioniert, können Sie diesen einfachen Code ausführen

    std::cout << "0x0 ^ 0x0 = " << ( 0x0 ^ 0x0 ) << std::endl;
    std::cout << "0x0 ^ 0x1 = " << ( 0x0 ^ 0x1 ) << std::endl;
    std::cout << "0x1 ^ 0x0 = " << ( 0x1 ^ 0x0 ) << std::endl;
    std::cout << "0x1 ^ 0x1 = " << ( 0x1 ^ 0x1 ) << std::endl;

Die Ausgabe wird sein

0x0 ^ 0x0 = 0
0x0 ^ 0x1 = 1
0x1 ^ 0x0 = 1
0x1 ^ 0x1 = 0

Also dieser Ausdruck

0 != ( x ^ 0x1 )

wird nur dann wahr sein, wenn x! = 0x1.

Es ändert sich nicht x selbst. Es wird nur überprüft, ob x gleich 0 oder 1 ist. Dieser Ausdruck könnte in geändert werden

if ( x != 0x1 )

Es prüft, dass x eigentlich nicht 0x1 ... x 0x1 ing x mit 0x1 wird nur 0 ergeben, wenn x 0x1 ... das ist ein alter Trick, der meistens in Assembler verwendet wird


Ich würde vermuten, dass es andere Bits oder Bitfeldwerte in x , und dies soll testen, dass nur das niederwertige Bit gesetzt ist. Im Kontext würde ich vermuten, dass dies der Standardwert ist und dass daher die Kodierung von diesem und einigen verwandten m (wahrscheinlich teurer zu kodieren) übersprungen werden kann, da sie beide der Standardwert sein müssen, der in einem Konstruktor oder ähnlichem initialisiert wird .

Irgendwie muss der Decoder folgern können, dass diese Werte fehlen. Wenn sie sich am Ende einer Struktur befinden, können sie über einen length kommuniziert werden, der immer vorhanden ist.


Wie ich bisher gesehen habe, fehlt eine einfache Regel für den Umgang mit XOR . Ohne ins Detail zu gehen, was ^ und 0x bedeuten (und if , und != Etc), kann der Ausdruck 0 != (x^1) wie folgt nachgearbeitet werden, indem (a^a)==0 :

0 != (x^1) <=> [xor left and right side by 1]
(0^1) != (x^1^1) <=>
1 != x

^ ist bitweise xor operator in c . In Ihrem Fall wird x mit 1 xoriert, zum Beispiel hat x den Wert 10, dann 10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d so wird die Bedingung wahr.


  • ^ ist die bitweise XOR Operation
  • 0x1 ist 1 in Hex-Notation
  • x ^ 0x1 invertiert das letzte Bit von x (siehe die XOR-Wahrheitstabelle im obigen Link, falls Ihnen das nicht klar ist).

Also wird die Bedingung (0 != ( x ^ 0x1 )) wahr sein, wenn x größer als 1 ist oder wenn das letzte Bit von x 0 ist. Das lässt nur x == 1 als einen Wert, bei dem die Bedingung falsch ist . So ist es gleichbedeutend mit

if (x != 1)

PS Hölle einer Möglichkeit, solch eine 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 flehe dich an.







bitmask