13

Let me start by saying I have never really worked with bits before in programming. I have an object that can be in 3 states and I want to represent those states using a 3 bit array.
For example:

I have a race car and it can go forward,left, and right at a stand still the bits would be 000
If the car was moving forward the bits would be 010 if forward and left it would be 110 etc...

How would I set the bits and how could I read them back to get the values?

Tegra Detra
  • 24,551
  • 17
  • 53
  • 78
  • The reason I was interested in using this approach is because I was going to be transporting this information over a network and every bit is really going to count. I figured that I would have to use a whole byte to send the data which is good because I can sneak some extra data in there, I think I am going to read those links on bit masking. If some one could give me an example of that that would be wonderfull – Tegra Detra Oct 27 '10 at 12:10
  • 1
    I would use an array of boolean values until I had to send it across the network, then I would compress/decompress these into a byte, if necessary. – NomadMaker Mar 03 '20 at 23:23

5 Answers5

13

I would suggest using BitSet along with 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();
}
palako
  • 3,342
  • 2
  • 23
  • 33
Emil
  • 13,577
  • 18
  • 69
  • 108
10

If size and speed is important, use bits in a byte. (Read the links posted in the other answer as there are non-obvious complications when using and casting signed datatypes.)

This encodes for the speeds: stand, left, left_forward, forward, right_forward, and 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();
}

}

Output:

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

Note also that Left and Right is mutually exclusive, so its possible to create an illegal combination. (7 = 111 )

If you actually meant that a thing can only move LEFT, FORWARD or RIGHT, then you don't need flags, just enums.

This enum is possible to transport in only two bits.

    enum Direction{
    NONE, FORWARD, RIGHT, LEFT;

}


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

The final two bits in enc will become:

00 : none  
01 : forward;
10 : right
11 : left
KarlP
  • 5,149
  • 2
  • 28
  • 41
4

The least you'll need to store these three bits is one byte.

Read this tutorial on bitwise operators to get started.

Edit: this page on bit masks may also be very helpful.

mdrg
  • 3,242
  • 2
  • 22
  • 44
3

You say three states, but you've actually got six: forward, forward-left, forward-right, left, right, stand-still. Unless your race car doesn't move sideways ofcourse, then you've got four.

You should really use an enum for this:

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL }

Since left, right and forward are mutually exclusive, this isn't a very good fit for a bit-fiddling program. You'll get into all kinds of consistency problems.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 2
    Unless you need to serialize your object over a medium were every byte counts, use enums. They are more legible and have features that allow you to do loops over the state or switch statements. Even if you do need a compressed format, it would be easier to use enums and then build the compressed version as needed. – unholysampler Oct 27 '10 at 10:58
  • Thus avoiding the consistency problem until deserialization. Thanks, unholysampler. – Fred Foo Oct 27 '10 at 11:02
  • I in fact am serializing over a medium where every bit counts, thats my fault for not being explicit. – Tegra Detra Oct 27 '10 at 12:03
2

In java.util there is a class called BitSet that makes bit manipulation very simple.

In your case you could create a BitSet of size 3 and then use the get() and set() methods to set a check the bits.

Aaron
  • 5,931
  • 4
  • 27
  • 31