2010-10-27 9 views
11

Laissez-moi commencer par dire que je n'ai jamais vraiment travaillé avec des bits auparavant en programmation. J'ai un objet qui peut être dans 3 états et je veux représenter ces états en utilisant un tableau de 3 bits.
Par exemple:

J'ai une voiture de course et il peut aller de l'avant, à gauche, et à droite sur un stand encore les bits serait 000
Si la voiture se déplaçait en avant les bits seraient 010 si avant et laissé serait 110 etc ...

Comment pourrais-je définir les bits et comment pourrais-je les lire pour obtenir les valeurs?Java Travailler avec des bits

+0

La raison pour laquelle je me suis intéressé à utiliser cette approche parce que j'allait être le transport de ces informations sur un réseau et chaque bit va vraiment compter. Je me suis dit que je devais utiliser un octet entier pour envoyer les données, ce qui est bien parce que je peux y glisser des données supplémentaires, je pense que je vais lire ces liens sur le masquage des bits. Si quelqu'un pouvait me donner un exemple de ce qui serait merveilleux – Prospero

Répondre

9

Si la taille et la vitesse est importante, utiliser les bits dans un octet. (Lisez les liens affichés dans l'autre réponse car il y a des complications non évidentes lors de l'utilisation et de la fusion de types de données signés.)

Ceci code pour les vitesses: stand, left, left_forward, forward, right_forward et 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(); 
} 

} 

Sortie:

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

Notez également que gauche et droite sont mutuellement exclusives, il est donc possible de créer une combinaison illégale. (7 = 111)

Si vous vouliez réellement dire qu'une chose ne peut se déplacer que GAUCHE, AVANT ou DROITE, alors vous n'avez pas besoin de drapeaux, juste des enums.

Cette énumération ne peut être transportée que sur deux bits.

enum Direction{ 
    NONE, FORWARD, RIGHT, LEFT; 

} 


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

Les deux derniers bits enc deviendront:

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

Le minimum nécessaire pour stocker ces trois bits est byte.

Lire this tutorial sur les opérateurs bit à bit pour commencer.

Modifier: this page sur les masques binaires peut également être très utile.

3

Vous dites trois états, mais vous en avez en réalité six: avant, avant gauche, avant droite, gauche, droite, stand-still. À moins que votre voiture de course ne bouge pas de côté, vous en avez quatre.

Vous devriez vraiment utiliser un enum pour cela:

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL } 

Depuis gauche, à droite et en avant sont mutuellement exclusifs, ce n'est pas un très bon moyen pour un programme peu-tripoter. Vous aurez toutes sortes de problèmes de cohérence.

+2

À moins que vous ayez besoin de sérialiser votre objet sur un support si chaque octet compte, utilisez enums. Ils sont plus lisibles et ont des caractéristiques qui vous permettent de faire des boucles sur l'état ou de changer de déclaration. Même si vous avez besoin d'un format compressé, il serait plus facile d'utiliser des énumérations, puis de générer la version compressée en fonction des besoins. – unholysampler

+0

Évitant ainsi le problème de cohérence jusqu'à la désérialisation. Merci, nonholysampler. –

+0

Je suis en fait sérialiser sur un support où chaque bit compte, c'est ma faute de ne pas être explicite. – Prospero

2

Dans java.util il existe une classe appelée BitSet qui rend la manipulation des bits très simple.

Dans votre cas, vous pouvez créer un BitSet de taille 3, puis utiliser les méthodes get() et set() pour définir une vérification des bits.

10

Je suggère d'utiliser BitSet ainsi que de 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

Merci pour votre réponse. La réponse de KarlP vaut la note. J'ai en fait utilisé votre exemple dans le code. – Prospero

+0

http://indianjavalearners.blogspot.in/p/blog-page.html lorsque nous utilisons enum –