Вопрос
Позвольте мне начать с того, что я никогда не работал с битами раньше в программировании. У меня есть объект, который может быть в 3 штатах, и я хочу представлять эти состояния, используя 3-битный массив.
Например:
У меня есть гоночная машина, и она может идти вперед, слева, и прямо на стойке все еще биты будут 000
Если машина движется вперед, биты будут 010, если вперед и оставить, это будет 110 и т. Д.
Как бы я установил биты и как я могу прочитать их обратно, чтобы получить ценности?
Решение
Если размер и скорость важны, используйте биты в байте. (Прочитайте ссылки, размещенные в другом ответе, так как при использовании и отличных данных о осложнениях существует неочевидные осложнения.)
Это кодирует для скоростей: стенд, слева, left_forward, вперед, right_forward и вправо.
public class Moo {
final static byte FORWARD = 0x1; // 00000001
final static byte LEFT =0x2; // 00000010
final static byte RIGHT =0x4; // 00000100
/**
* @param args
*/
public static void main(String[] args) {
byte direction1 = FORWARD|LEFT; // 00000011
byte direction2 = FORWARD|RIGHT; // 00000101
byte direction3 = FORWARD|RIGHT|LEFT; // 00000111
byte direction4 = 0;
// someting happens:
direction4 |= FORWARD;
// someting happens again.
direction4 |= LEFT;
System.out.printf("%x: %s\n", direction1, dirString(direction1));
System.out.printf("%x: %s\n", direction2, dirString(direction2));
System.out.printf("%x: %s\n", direction3, dirString(direction3));
System.out.printf("%x: %s\n", direction4, dirString(direction4));
}
public static String dirString( byte direction) {
StringBuilder b = new StringBuilder("Going ");
if( (direction & FORWARD) > 0){
b.append("forward ");
}
if( (direction & RIGHT) > 0){
b.append("turning right ");
}
if( (direction & LEFT) > 0){
b.append("turning left ");
}
if( (direction &( LEFT|RIGHT)) == (LEFT|RIGHT)){
b.append(" (conflicting)");
}
return b.toString();
}
}
Выход:
3: Going forward turning left
5: Going forward turning right
7: Going forward turning right turning left (conflicting)
3: Going forward turning left
Обратите внимание, что влево и справа - это взаимно эксклюзивное, так это возможно создать незаконное комбинацию. (7 = 111)
Если вы на самом деле имели в виду, что вещь может двигаться только влево, вперед или вправо, тогда вам не нужны флаги, просто перемывание.
Этот Enum можно транспортировать только только в двух битах.
enum Direction{
NONE, FORWARD, RIGHT, LEFT;
}
Direction dir = Direction.FORWARD;
byte enc = (byte) dir.ordinal();
Последние два бита в enc
станет:
00 : none
01 : forward;
10 : right
11 : left
Другие советы
Я бы предложил использовать Bitset вместе с Enum's
enum State { LEFT, RIGHT, FORWARD,STAND_STILL}
BitSet stat=new BitSet(4);
void setLeft() // and so on for each state
{
stat.set(State.LEFT);
}
boolean isLeft()
{
stat.get(State.LEFT);
}
void reset() //reset function to reset the state
{
stat.clear();
}
Наименее вам нужно хранить эти три бита, это один byte
.
Читать Это руководство на битовых операторах, чтобы начать работу.
Редактировать: эта страница на битах маски также могут быть очень полезными.
Вы говорите три штата, но вы на самом деле получили шесть: вперед, вперед, левый, вперед-правый, слева, справа, стоять - все еще. Если ваша гоночная машина не движется вбок курса, то у вас есть четыре.
Вы должны действительно использовать порицать за это:
enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL }
Поскольку слева, вправо и вперед являются взаимоисключающими, это не очень хорошо подходит для программы Bit-Firedling. Вы попадете во все виды проблем согласованности.
В Java.util есть класс под названием Битет Это делает битовые манипуляции очень просто.
В вашем случае вы можете создать BitSet размер 3, а затем используйте методы GET () и SET () для установки проверки битов.