Java Работа с битами - PullRequest
       31

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

13 голосов
/ 27 октября 2010

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

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

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

Ответы [ 5 ]

10 голосов
/ 27 октября 2010

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

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

Это кодирует для скоростей: стоять, влево, влево, вперед, вперед, вправо и вперед.

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
4 голосов
/ 27 октября 2010

Минимум, что вам понадобится для хранения этих трех битов, - это один byte.

Чтение этого руководства по побитовым операторам для начала работы.

Редактировать: эта страница о битовых масках также может быть очень полезна.

3 голосов
/ 27 октября 2010

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

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

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL }

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

2 голосов
/ 27 октября 2010

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

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

...