Битовая манипуляция в Java - условно переключаемые биты на основе битовых значений? - PullRequest
2 голосов
/ 22 февраля 2020

У меня есть 8 объектов, которые мы будем называть «огни». Каждый источник света может быть включен или выключен (0 или 1). Каждый источник света имеет индекс (0-7).

Я не знаком с побитовыми операциями в Java, но я думаю, что следующий код проверяет, правильно ли включен или выключен источник света:

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

В настоящее время я сталкиваюсь с проблемой невозможности включить все огни. Например, если лампочка 0 включена, а я включаю лампу 1, лампочка 1 сообщит, что она включена, но лампочка 0 сообщит, что она выключена. Это с помощью следующего кода:

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

Я знаю, что неправильно его установил. Я просто не могу понять, как это сделать. Этот материал не совсем вычисляется в моем мозгу. Я прочитал о всех побитовых операторах, и это все еще не имеет смысла для меня. Может кто-нибудь объяснить мне, что я делаю не так?

Ответы [ 3 ]

2 голосов
/ 22 февраля 2020

Ваш подход к "включению света" в порядке.

Вы можете подумать, что он сломан, потому что есть ошибка в том, как вы проверяете, включен ли "свет". Давайте разберем это:

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

Начиная с самых внутренних скобок, вы пересекаете index с 1. Это приводит к сдвигу value на один бит, если индекс нечетный, и ничего не делает, если индекс равен even.

Затем вы сравниваете результат сдвига с 1.

Если value равно 3, а index равно нулю, вы получите ошибочный false результат. Если value больше трех, вы получите false независимо от index, что может быть ошибочным.

Такое выражение даст ожидаемые результаты:

boolean lightIsOn = ((value >>> index) & 1) == 1;
2 голосов
/ 22 февраля 2020

Я обычно использую отладку для такого рода вещей. Хотя здорово просто разобраться в этом, иногда приятно видеть фактический битсет. Я закомментировал промежуточные операторы отладки после того, как увидел, что они работают правильно:

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));
    }
  }
}
0 голосов
/ 22 февраля 2020

Надеюсь, что это может вам помочь.

Если ваш номер света меньше 32.

Вы можете попробовать использовать битовые вычисления для каждого источника света. Например:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...