Ich habe 8 Objekte, die wir "Lichter" nennen werden. Jedes Licht kann ein- oder ausgeschaltet werden (0 oder 1). Jedes Licht hat einen Index (0-7).

Ich bin mit Bitwise-Operationen in Java nicht vertraut, aber ich denke, der folgende Code prüft, ob das Licht richtig ein- oder ausgeschaltet ist:

int value = 128;
int index = light.getIndex();
boolean lightIsOn = (value >> (index & 0x1) == 1);

Ich stehe derzeit vor dem Problem, nicht alle Lichter einschalten zu können. Wenn zum Beispiel Licht 0 an ist und ich Licht 1 einschalte, sagt Licht 1, dass es an ist, aber Licht 0 sagt dann, dass es aus ist. Das ist mit folgendem Code:

if (!lightIsOn) {
   value = (value | 1 << index);
}

Ich weiß, dass ich es falsch einstelle. Ich kann einfach nicht herausfinden, wie es geht. Dieses Zeug rechnet nicht genau in meinem Gehirn. Ich habe alle Bitwise-Operatoren gelesen und es macht für mich immer noch keinen Sinn. Kann mir bitte jemand erklären, was ich falsch mache?

2
David 22 Feb. 2020 im 03:03

3 Antworten

Beste Antwort

Ihr Ansatz zum "Einschalten des Lichts" ist in Ordnung.

Sie könnten denken, dass es kaputt ist, weil es einen Fehler gibt, wie Sie testen, ob ein "Licht" an ist. Lassen Sie es uns zusammenfassen:

boolean lightIsOn = (value >> (index & 0x1) == 1);

Beginnend mit den innersten Klammern schneiden Sie index mit 1. Dies führt dazu, dass value um ein Bit verschoben wird, wenn der Index ungerade ist, und nichts getan wird, wenn der Index gerade ist.

Dann vergleichen Sie das Ergebnis der Verschiebung mit 1.

Wenn value 3 und index Null ist, erhalten Sie ein fehlerhaftes false Ergebnis. Wenn value größer als drei ist, erhalten Sie false unabhängig von index, was möglicherweise fehlerhaft ist.

Ein Ausdruck wie dieser führt zu beabsichtigten Ergebnissen:

boolean lightIsOn = ((value >>> index) & 1) == 1;
2
erickson 22 Feb. 2020 im 00:45

Hoffe es kann dir helfen.

Wenn Ihre Lichtzahl kleiner als 32 ist.

Sie könnten versuchen, Bit-Computing für jedes Licht zu verwenden. Beispielsweise:

light1: 1
light2: 2
light3: 4
light4: 8
light5: 16
light6: 32
light7: 64
light8: 128

So If the mumber is 2: that will be light2
So If the mumber is 3: that will be light1 and light2
So If the mumber is 15: that will be light1,light2,light3,light4
0
YouXiang-Wang 22 Feb. 2020 im 00:22

Ich benutze normalerweise das Debuggen für solche Dinge. Während es großartig ist, es einfach im Kopf zu klären, ist es manchmal schön, das eigentliche Bitset zu sehen. Ich habe die Zwischen-Debug-Anweisungen auskommentiert, nachdem ich gesehen habe, dass sie korrekt funktionieren:

public class StackOverflowTest {
  int value = 128;

  public static void main(String[] args){
    StackOverflowTest test = new StackOverflowTest();
    System.out.println(Integer.toBinaryString(test.value));
    System.out.println("is 7 on? " + test.lightIsOn(7));

    System.out.println("\n-- turnOff(7) --");
    test.turnOff(7);
    System.out.println("is 7 on? " + test.lightIsOn(7));
    System.out.println(Integer.toBinaryString(test.value));    

    System.out.println("\n-- turnOn(4) --");
    test.turnOn(4);
    System.out.println("is 4 on? " + test.lightIsOn(4));
    System.out.println(Integer.toBinaryString(test.value));
  }

  boolean lightIsOn(int index) {
//    System.out.println(Integer.toBinaryString(value));
//    System.out.println(Integer.toBinaryString(index & 0x1));
//    System.out.println(Integer.toBinaryString(value >> index));
//    System.out.println(Integer.toBinaryString((value >> index) & 0x1));
//    System.out.println(Integer.toBinaryString(value));
//    return value >> (index & 0x1) == 1; // this is not working
    return ((value >> index) & 0x1) == 1;
  }

  void turnOff(int index) {
    if (lightIsOn(index)) {
//      System.out.println(Integer.toBinaryString(value));
//      System.out.println(Integer.toBinaryString(1 << index));
//      System.out.println(Integer.toBinaryString(value));
      value = (value ^ (1 << index));
    }
  }

  void turnOn(int index) {
    if (!lightIsOn(index)) {
//      System.out.println(Integer.toBinaryString(value));
//      System.out.println(Integer.toBinaryString(1 << index));
//      System.out.println(Integer.toBinaryString(value));
      value = (value | (1 << index));
    }
  }
}
2
Scratte 22 Feb. 2020 im 00:56