Was bedeutet "(int) Wert & 0x1, (int) Wert & 0x2, (int) Wert & 0x4, (int) Wert & 0x8"?

11

Code

Der "Wert" reicht von 0 bis 15 (seine möglichen Werte). Wann werden diese 4 "Wenn" -Bedingungen erfüllt? Wenn mein (int) Wert = 2 ist, bedeutet das 0010?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }
Sean McCarthy
quelle
3
Dies sind Bitmasken , die nach einzelnen Bits suchenvalue (gelesen if(value & 0x4)als "Ist das 3. Bit von valueset (= 1)). Da Sie anscheinend Probleme haben, den Code zu verstehen, gehe ich davon aus, dass er nicht Ihnen gehört. Dies (und die Tatsache, dass Sie nicht fragen." zur Überprüfung) macht diese Frage für CR.SE nicht zum Thema .
Niemand
Zum besseren Verständnis verwendet ähnlicher Code, der nach C # portiert wurde, die Enum.HasFlagMethode zum Testen auf Bits. Siehe: Enum.HasFlag .
Rwong

Antworten:

12

Jede Zahl kann so ausgedrückt werden, dass value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...jedes b entweder 0oder ist 1(dies sind die Bits der Darstellung). Dies ist die binäre Darstellung.

Das binäre UND ( &) nimmt jedes dieser bPaare weise und führt UND auf ihnen aus. Dies hat die folgenden Ausgänge:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

Mit Zweierpotenzen (die nur ein einziges Bit aktivieren) können wir die einzelnen Bits isolieren und testen:

  • value & 1ist wahr, wenn valueungerade ist {1, 3, 5, 7, 9, 11, 13, 15}.

  • value & 2ist wahr, wenn value/2ungerade ist {2, 3, 6, 7, 10, 11, 14, 15}.

  • value & 4ist wahr, wenn value/4ungerade ist {4, 5, 6, 7, 12, 13, 14, 15}.

  • value & 8ist wahr, wenn value/8ungerade ist {8, 9, 10, 11, 12, 13, 14, 15}.

Die 0x vorangestelltem auf die Zahlen Mittel sollte sie als interpretiert werden hexadezimale Zahl . Es ist ein bisschen überflüssig, wenn Sie nur auf 0x8 gehen, aber den Betreuern mitteilen, dass es wahrscheinlich als Bitmaske verwendet wird.

Ratschenfreak
quelle
1
Der Wortlaut könnte darauf hindeuten, dass er auf alle Zahlen erweitert werden kann, was nicht wahr ist: 8/6ungerade, während 8&6falsch ergibt.
Sjoerd
@Sjoerd deshalb habe ich "Powers of 2" gesagt
Ratschenfreak
5

Diese if-Anweisungen prüfen, ob ein bestimmtes Bit von valuegesetzt ist.

Für den Hexadezimalwert 0x4ist beispielsweise das 3. Bit von rechts auf 1und alle anderen Bits auf gesetzt 0. Wenn Sie den Binär- und Operator ( &) mit zwei Operanten verwenden, werden für das Ergebnis alle Bits gesetzt, mit 0Ausnahme der Bits, die in beiden Operanten 1 sind.

Wenn Sie also die Berechnung durchführen value & 0x4, erhalten Sie entweder binär 00000000oder binär 00000100, je nachdem, ob das 3. Bit von valueist 1oder nicht 0. Der erste falsewird als und der zweite als ausgewertet true, sodass der if-Block nur für Werte ausgeführt wird, bei denen das dritte Bit gesetzt ist.

Philipp
quelle
1

Hier sind zwei interessante Dinge zu beachten.

Erstens ist dies ein übliches Muster zum Überprüfen jedes der 4 Bits niedriger Ordnung eines Integralwerts. Die if-Bedingung ist erfüllt, wenn das entsprechende Bit gesetzt ist. Für den Wert 2 ist das Bitmuster tatsächlich 0010.

Die andere interessantere Frage ist, warum die (int)Besetzung? Abgesehen von dem schlechten Stil der Verwendung von C-Casts in C ++ erfordern diese Ganzzahlen keine Ganzzahl- oder Zeichenwerte. Ein Bool macht keinen Sinn, ein Double / Float würde in eine temporäre Ganzzahl konvertiert und es wäre ungewöhnlich, Literalwerte zum Testen einer Aufzählung zu verwenden. Mit einem Zeiger mag es sinnvoll sein, aber das wäre eine sehr spezielle Verwendung. Fazit: Die Besetzung macht keinen Sinn.

david.pfx
quelle