代码之家  ›  专栏  ›  技术社区  ›  Tegra Detra

使用位的Java

  •  13
  • Tegra Detra  · 技术社区  · 14 年前

    首先,我要说的是,我以前在编程中从未真正使用过bits。我有一个可以处于3种状态的对象,我想用一个3位数组来表示这些状态。
    例如:

    我有一辆赛车,它可以前进,左,右停在一个停车位,位是000。
    如果汽车向前行驶,向前和向左的位将为010,则为110等。

    我如何设置这些位,以及如何读取它们以获取值?

    5 回复  |  直到 14 年前
        1
  •  9
  •   KarlP    10 年前

    如果大小和速度很重要,请使用字节中的位。(请阅读另一个答案中发布的链接,因为在使用和强制转换签名数据类型时没有明显的并发症。)

    这是对速度的编码:站,左,左,前,右,右。

    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
    
        2
  •  10
  •   Emil    14 年前

    我建议与枚举一起使用位集

    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();
    }
    
        3
  •  4
  •   mdrg    14 年前

    至少你需要存储这三个位是一个 byte .

    this tutorial 开始使用位运算符。

    编辑: this page 戴上防毒面具也很有帮助。

        4
  •  3
  •   Fred Foo    14 年前

    你说三种状态,但实际上你有六种状态:向前,向左,向右,向左,向右,静止。当然,除非你的赛车没有侧向移动,否则你就有四辆了。

    你真的应该使用 enum 为此:

    enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL }
    

    由于左、右和前是互斥的,所以这不是一个非常适合有点烦人的程序。你会遇到各种各样的一致性问题。

        5
  •  2
  •   Aaron    14 年前

    在java.util中有一个名为 BitSet