2010-10-27 3 views
11

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

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

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

+0

Поэтому я был заинтересован в использовании этого подхода заключается в том, потому что я собирался быть транспортировать эту информацию по сети, и каждый бит действительно происходит считать. Я решил, что мне нужно будет использовать целый байт, чтобы отправить данные, которые хороши, потому что я могу прокрасть туда некоторые дополнительные данные, я думаю, что буду читать эти ссылки на бит-маскировку. Если кто-то может дать мне пример того, что было бы замечательно – Prospero

ответ

9

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

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

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 Direction{ 
    NONE, FORWARD, RIGHT, LEFT; 

} 


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

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

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

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

Прочтите this tutorial по побитовым операторам, чтобы начать работу.

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

3

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

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

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL } 

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

+2

Если вам не нужно сериализовать свой объект над средой, каждый байт подсчитывал, используйте перечисления. Они более разборчивы и имеют функции, которые позволяют выполнять циклы над состояниями или операторами switch. Даже если вам нужен сжатый формат, было бы проще использовать перечисления, а затем при необходимости создавать сжатую версию. – unholysampler

+0

Таким образом, избегая проблемы согласованности до десериализации. Спасибо, unholysampler. –

+0

Я на самом деле сериализуюся над средой, где каждый бит подсчитывается, вот и моя вина за то, что я не был явным. – Prospero

2

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

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

10

Я предложил бы использовать BitSet вместе с

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(); 
} 
+0

Благодарим вас за ответ. Ваш ответ KarlP стоит галочку. Я фактически использовал ваш пример в коде. – Prospero

+0

http://indianjavalearners.blogspot.in/p/blog-page.html , когда мы используем перечисление –

Смежные вопросы