Java 中的位操作 - 根据位值有条件地切换位?

Bit Manipulation in Java - Conditionally Toggling Bits Based on Bit Values?

我有 8 个我们将调用的对象 "lights"。每个灯都可以打开或关闭(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);
}

我知道我设置不当。我只是不知道该怎么做。这些东西并不能完全在我的大脑中计算。我已经阅读了所有按位运算符,但它对我来说仍然没有真正意义。任何人都可以向我解释我做错了什么吗?

希望对您有所帮助。

如果你的灯号小于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

您对 "turning on the light" 的处理方式还不错。

您可能认为它已损坏,因为在测试 "light" 是否打开时存在错误。让我们分解一下:

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

从最里面的括号开始,您将 index 与 1 相交。如果索引为奇数,这将导致移动 value 一位,如果索引为偶数,则不执行任何操作。

然后你将移位的结果与 1 进行比较。

如果 value 为 3 而 index 为零,您将得到错误的 false 结果。如果 value 大于三,则不管 index,你都会得到 false,这可能是错误的。

像这样的表达式将给出预期的结果:

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

我通常对这类事情使用调试。虽然在脑海中将其整理出来很好,但有时很高兴看到实际的位集。在我看到它工作正常后,我注释掉了中间调试语句:

public class WhosebugTest {
  int value = 128;

  public static void main(String[] args){
    WhosebugTest test = new WhosebugTest();
    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));
    }
  }
}