2010-10-27 30 views
11

Permítanme comenzar diciendo que nunca antes había trabajado con bits en la programación. Tengo un objeto que puede estar en 3 estados y quiero representar esos estados usando una matriz de 3 bits.
Por ejemplo:

Tengo un coche de carreras y que puedo seguir adelante, izquierda y derecha en una posición todavía los bits sería 000
Si el coche se movía hacia adelante los bits serían 010 si hacia adelante y lo dejó Sería 110 etc ...

¿Cómo establecería los bits y cómo podría leerlos para obtener los valores?Java Trabajar con bits

+0

La razón por la que estaba interesado en el uso de este enfoque es porque yo iba a ser el transporte de esta información a través de una red y cada bit es realmente está pasando para contar. Pensé que tendría que usar un byte completo para enviar los datos, lo cual es bueno porque puedo obtener algunos datos adicionales, creo que voy a leer esos enlaces en el enmascaramiento de bits. Si alguien pudiera darme un ejemplo de eso sería maravilloso – Prospero

Respuesta

9

Si el tamaño y la velocidad es importante, utilice brocas de enumeración en un byte. (Lea los enlaces publicados en la otra respuesta ya que existen complicaciones no obvias al usar y enviar tipos de datos firmados).

Esto codifica las velocidades: stand, left, left_forward, forward, right_forward y 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(); 
} 

} 

Salida:

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

Tenga en cuenta también que la izquierda y la derecha es mutuamente excluyentes, por lo que su posible crear una combinación ilegal. (7 = 111)

Si realmente quiso decir que una cosa solo puede moverse hacia la IZQUIERDA, HACIA ADELANTE o hacia la DERECHA, entonces no necesita banderas, solo enumeraciones.

Esta enumeración se puede transportar en solo dos bits.

enum Direction{ 
    NONE, FORWARD, RIGHT, LEFT; 

} 


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

Los dos últimos bits en enc se convertirán:

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

Lo menos que necesitará para almacenar estos tres bits es uno byte.

Lea this tutorial en operadores bit a bit para empezar.

Editar: this page en máscaras de bits también pueden ser muy útiles.

3

Dice tres estados, pero en realidad tiene seis: adelante, adelante-izquierda, adelante-derecha, izquierda, derecha, parada. A menos que tu auto de carreras no se mueva de lado, entonces tienes cuatro.

que realmente debe utilizar un enum para esto:

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL } 

Desde la izquierda, la derecha y hacia adelante son mutuamente excluyentes, esto no es una muy buena opción para un programa de bits de tocar el violín. Obtendrá todo tipo de problemas de consistencia.

+2

A menos que necesite serializar su objeto en un medio donde cada byte cuenta, use enumeraciones. Son más legibles y tienen características que le permiten hacer bucles sobre el estado o cambiar las declaraciones. Incluso si necesita un formato comprimido, sería más fácil usar enumeraciones y luego compilar la versión comprimida según sea necesario. – unholysampler

+0

Evitando así el problema de consistencia hasta la deserialización. Gracias, profano. –

+0

De hecho estoy serializando en un medio donde cada bit cuenta, esa es mi culpa por no ser explícita. – Prospero

2

En java.util hay una clase llamada BitSet que hace que la manipulación de bits sea muy simple.

En su caso, podría crear un BitSet de tamaño 3 y luego usar los métodos get() y set() para establecer una comprobación de los bits.

10

se recomienda usar BitSet junto con

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

Gracias por su respuesta. Su respuesta de KarlP vale la marca. De hecho, utilicé tu ejemplo en el código. – Prospero

+0

http://indianjavalearners.blogspot.in/p/blog-page.html cuando usamos enum –