2010-10-27 6 views
11

Vorrei iniziare dicendo che non ho mai lavorato con i bit prima della programmazione. Ho un oggetto che può essere in 3 stati e voglio rappresentare quegli stati usando un array a 3 bit.
Per esempio:

ho una macchina da corsa e si può andare avanti, a sinistra ea destra in una posizione ancora i bit sarei 000
Se la vettura era in movimento in avanti le punte sarebbero 010 se in avanti e lasciato sarebbe 110 ecc ...

Come impostarei i bit e come potrei leggerli per ottenere i valori?Java Lavorare con i bit

+0

La ragione per cui ero interessato a utilizzare questo approccio è perché mi stava per essere il trasporto di queste informazioni su una rete e ogni bit è realmente accadendo contare. Ho pensato che avrei dovuto usare un intero byte per inviare i dati che è buono perché posso introdurre alcuni dati extra lì dentro, penso che leggerò questi link sul bit masking. Se qualcuno potrebbe darmi un esempio di ciò sarebbe meraviglioso. – Prospero

risposta

9

Se la dimensione e la velocità è importante, utilizzare bit in un byte. (Leggi i collegamenti pubblicati nell'altra risposta in quanto vi sono complicazioni non ovvie quando usi e trasmetti tipi di dati firmati.)

Questo codifica per le velocità: stand, left, left_forward, forward, right_forward e 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(); 
} 

} 

uscita:

3: Going forward turning left 
5: Going forward turning right 
7: Going forward turning right turning left (conflicting) 
3: Going forward turning left 

Si noti inoltre che sinistra e destra sono escludono a vicenda, per cui il suo possibile la creazione di una combinazione illegale. (7 = 111)

Se in realtà intendevi che una cosa può muoversi solo a SINISTRA, AVANTI o DESTRA, allora non hai bisogno di bandiere, solo di enumerazioni.

Questo enum è possibile trasportare in soli due bit.

enum Direction{ 
    NONE, FORWARD, RIGHT, LEFT; 

} 


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

Gli ultimi due bit in enc diventeranno:

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

Il minimo che è necessario memorizzare questi tre bit è uno byte.

Leggi this tutorial su operatori bit a bit per iniziare.

Modifica: this page Le maschere di bit possono anche essere molto utili.

3

Tu dici tre stati, ma in realtà ne hai sei: avanti, avanti-sinistra, avanti-destra, sinistra, destra, stand-still. A meno che la tua macchina da corsa non si muova lateralmente, allora ne hai quattro.

Si dovrebbe davvero utilizzare un enum per questo:

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL } 

Da sinistra, a destra e in avanti si escludono a vicenda, non si tratta di una misura molto buona per un programma di po-giocherellare. Potrai entrare in tutti i tipi di problemi di coerenza.

+2

A meno che non sia necessario serializzare l'oggetto su un supporto, ogni byte conta, usa l'enumerazione. Sono più leggibili e hanno caratteristiche che ti permettono di fare loop sullo stato o cambiare le istruzioni. Anche se hai bisogno di un formato compresso, sarebbe più semplice usare le enumerazioni e quindi creare la versione compressa, se necessario. – unholysampler

+0

Evitando così il problema di coerenza fino alla deserializzazione. Grazie, unholysampler. –

+0

In effetti sto serializzando su un mezzo in cui ogni bit conta, questo è il mio difetto per non essere esplicito. – Prospero

2

In java.util esiste una classe chiamata BitSet che semplifica la manipolazione dei bit.

Nel tuo caso potresti creare un BitSet di dimensione 3 e quindi usare i metodi get() e set() per impostare un controllo dei bit.

10

Io suggerirei di usare BitSet insieme di enum

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

Grazie per la risposta. La risposta di un KarlP vale entrambi il segno di spunta. In effetti ho usato il tuo esempio in codice. – Prospero

+0

http://indianjavalearners.blogspot.in/p/blog-page.html quando usiamo enum –