2016-03-21 10 views
3

abgerufen werden Manchmal stoße ich auf den folgenden Code. Ich glaube, dass es verwendet wird, um Werte als Bits darzustellen, und sie können zu einer einzigen Zahl kombiniert und später abgerufen werden.Wie Bits von Nummer

Die Zahl 34 besteht aus 01000000 und 00000100 oder 2 und 32. Wie arbeite ich das in Java aus? Irgendwie muss ich 2 mit einer Variablen vergleichen, um X und 32 tot eine andere Variable zu tun, Y zu tun.

Das folgende ist ein Beispiel mit einigen meiner Gedanken.

aus dem DotA Modding-Wiki.

DOTA_ABILITY_BEHAVIOR_HIDDEN    = 1 << 0, //Can be owned by a unit but can't be cast and won't show up on the HUD. 
DOTA_ABILITY_BEHAVIOR_PASSIVE    = 1 << 1, //Cannot be cast like above but this one shows up on the ability HUD. 
DOTA_ABILITY_BEHAVIOR_NO_TARGET   = 1 << 2, //Doesn't need a target to be cast, ability fires off as soon as the button is pressed. 
DOTA_ABILITY_BEHAVIOR_UNIT_TARGET   = 1 << 3, //Needs a target to be cast on. 
DOTA_ABILITY_BEHAVIOR_POINT    = 1 << 4, //Can be cast anywhere the mouse cursor is (if a unit is clicked it will just be cast where the unit was standing). 
DOTA_ABILITY_BEHAVIOR_AOE     = 1 << 5, //Draws a radius where the ability will have effect. Kinda like POINT but with a an area of effect display. 
//... 

Also dieses „Verhalten“, wie 1 gespeichert bekommen, 2, 4, 8, 16, 32, usw. Aber die ganze Idee scheint mehrere Arten in ein einzige Zahl/Bytes speichern zu können und diese später abrufen. Ich sehe Verwendungen wie folgt aus:

DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE 

Welche 34 zu sein scheint. Die einzige Kombination, die 34 ergeben würde, wäre diese und ich glaube, dass jede Kombination auf diese Weise einzigartig wäre, solange Sie nicht den gleichen Wert zweimal verwenden.

Wie kann ich diese beiden Nummern von der Nummer 34 abrufen? Und gibt es irgendwelche Einschränkungen in der Verwendung?

Antwort

4

Diese Sonderrufnummern sind Bitmasken, verwendet, um Satz und Auslesen Binärflags genannt.
Ein byte, short, int oder long Wert kann also mehrere dieser Flags enthalten.

Beispiel:

int flag1 = 0b0000001; // 1<<0, or 1 
int flag2 = 0b0000010; // 1<<1, or 2 
int flag3 = 0b0000100; // 1<<2, or 4 

kombinieren Fahnen:

int combined= flag1 | flag2; 

einen Flag zu setzen:

combined = combined | flag3; 

Um ein Kennzeichen rückgängig gemacht:

combined = combined & ~flag; 

Um zu überprüfen, ob ein Flag gesetzt ist:

boolean set3 = (combined & flag3) !=0; 
+0

Sidequestion: Ich bekomme Binärliterale werden nicht auf dieser Sprache Ebene unterstützt. Vielleicht ist es verwandt mit '(34 & 2 == 2)' ergibt den Fehler 'operator & kann nicht auf int angewendet werden ' – Madmenyo

+0

Das ist einfach ein Problem mit der Priorität: 34 & 2 == 2 bedeutet 34 & (2 == 2), Das verursacht den Compiler-Fehler, dass das Bitwise-and (&) nicht auf Int und Boolean angewendet werden kann. Verwenden Sie Klammern ((34 & 2) == 2) und alles ist in Ordnung. –

+0

Vorrang von Operatoren in Java: http://introcs.cs.princeton.edu/java/11precedence/ –

1
int x = DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE 

if (x & DOTA_ABILITY_BEHAVIOR_AOE == DOTA_ABILITY_BEHAVIOR_AOE) 
    // do stuff 

Sie können so viele Werte hinzufügen, die durch ein einzelnes Bit dargestellt werden, wie der Datentyp speichern kann.

+0

wusste, dass ich die Antwort wäre, da dies so einfach sein, aber '(34 & 2 == 2)' den Fehler 'Operator ergibt & nicht angewandt werden kann – Madmenyo

+0

' if ((x & DOTA_ABILITY_BEHAVIOR_AOE) == DOTA_ABILITY_BEHAVIOR_AOE) 'int' – Madmenyo

+0

Es sollte wahrscheinlich Uint –

-1

Da niemand Ihre Frage beantwortet hat:

Decimal 34 == Hex 0022 == Binary 0000 0000 0010 0010 

Ihre Werte

sind
DOTA_ABILITY_BEHAVIOR_HIDDEN  = 1 << 0, // 0000 0000 0000 0001 
DOTA_ABILITY_BEHAVIOR_PASSIVE  = 1 << 1, // 0000 0000 0000 0010 
DOTA_ABILITY_BEHAVIOR_NO_TARGET = 1 << 2, // 0000 0000 0000 0100 
DOTA_ABILITY_BEHAVIOR_UNIT_TARGET = 1 << 3, // 0000 0000 0000 1000 
DOTA_ABILITY_BEHAVIOR_POINT  = 1 << 4, // 0000 0000 0001 0000 
DOTA_ABILITY_BEHAVIOR_AOE   = 1 << 5, // 0000 0000 0010 0000 

Die beiden Werte, die OR‘sein kann ed zusammen zu machen decimal 34

DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AOE 
1

Über den Teil, wo Sie erwähnt haben, wie man die Bits zurückbekommt, um 34 zu erhalten. Ich werde eine "Lösung" veröffentlichen, um eine Idee über einen Weg zu geben, dies zu erreichen. Es ist wahrscheinlich nicht der beste Weg.

Sie erwähnt haben ...

DOTA_ABILITY_BEHAVIOR_HIDDEN    = 1 << 0 # 0 0 0 0 0 0 0 1 
DOTA_ABILITY_BEHAVIOR_PASSIVE    = 1 << 1 # 0 0 0 0 0 0 1 0 
DOTA_ABILITY_BEHAVIOR_NO_TARGET   = 1 << 2 # 0 0 0 0 0 1 0 0 
DOTA_ABILITY_BEHAVIOR_UNIT_TARGET   = 1 << 3 # 0 0 0 0 1 0 0 0 
DOTA_ABILITY_BEHAVIOR_POINT    = 1 << 4 # 0 0 0 1 0 0 0 0 
DOTA_ABILITY_BEHAVIOR_AOE     = 1 << 5 # 0 0 1 0 0 0 0 0 

und 34 in binär ist 0 0 1 0 0 0 1 0.

Wenn wir halten Verschiebung links und überprüfen, ob das Bit an der 0-ten Index sehen gesetzt.

List<Integer> indx = new ArrayList<Integer>(); 
int count = 0; 
while(n != 0) { 
    if(n & 0x1 == 1) 
     indx.add(count); 
    n = n >> 1; 
    count++; 
} 

Für 34 wird indx[1,5] enthalten. Sie können dies verwenden, um neu zu erstellen, welche Bits verwendet wurden, um [DOTA_ABILITY_BEHAVIOR_PASSIVE, DOTA_ABILITY_BEHAVIOR_AOE] zu bilden.

+0

Dies ist zwar nicht der beste Weg, aber es gibt Einblick in das, was vor sich geht. +1 – Madmenyo