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));
}
}
}
我有 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));
}
}
}