Подтвердить что ты не робот

Java Работа с битами

Позвольте мне начать с того, что я никогда раньше не работал с битами в программировании. У меня есть объект, который может быть в 3 состояниях, и я хочу представлять эти состояния, используя 3-битный массив.
Например:

У меня гоночный автомобиль, и он может идти вперед, влево и вправо на стойке, а бит будет 000
Если автомобиль двигался вперёд, бит был бы 010, если вперед и оставлено было бы 110 и т.д....

Как бы я установил биты и как я мог их прочитать, чтобы получить значения?

4b9b3361

Ответ 1

Если размер и скорость важны, используйте биты в байте. (Прочитайте ссылки, опубликованные в другом ответе, поскольку при использовании и литье подписанных типов данных возникают неочевидные осложнения.)

Это кодирует для скоростей: stand, left, left_forward, forward, right_forward и right.

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 

Обратите внимание, что Left и Right являются взаимоисключающими, поэтому можно создать незаконную комбинацию. (7 = 111)

Если вы на самом деле означали, что вещь может перемещаться только влево, вправо или вправо, тогда вам не нужны флаги, просто перечисления.

Это перечисление можно переносить только двумя битами.

    enum Direction{
    NONE, FORWARD, RIGHT, LEFT;

}


Direction dir = Direction.FORWARD;
byte enc = (byte) dir.ordinal();

Последние два бита в enc станут:

00 : none  
01 : forward;
10 : right
11 : left

Ответ 2

Я бы предложил использовать 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();
}

Ответ 3

Меньше всего вам нужно сохранить эти три бита: byte.

Прочтите этот учебник для побитовых операторов, чтобы начать.

Изменить: эта страница на бит-масках также может быть очень полезной.

Ответ 4

Вы говорите три состояния, но на самом деле у вас есть шесть: вперед, вперед-левый, вперед-правый, левый, правый, стоячий. Если ваш гоночный автомобиль не двигается боком, то у вас есть четыре.

Вы действительно должны использовать enum для этого:

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL }

Поскольку левые, правые и прямые взаимно исключают друг друга, это не очень хорошо подходит для программы бит-возиться. Вы столкнетесь со всеми проблемами последовательности.

Ответ 5

В java.util есть класс под названием BitSet, который делает манипуляции с битами очень простыми.

В вашем случае вы можете создать BitSet размера 3, а затем использовать методы get() и set(), чтобы установить проверку бит.