2010-10-27 22 views
11

Hãy để tôi bắt đầu bằng cách nói rằng tôi chưa bao giờ thực sự làm việc với bit trước khi lập trình. Tôi có một đối tượng có thể ở 3 trạng thái và tôi muốn đại diện cho các trạng thái đó bằng cách sử dụng mảng 3 bit.
Ví dụ:

Tôi có một chiếc xe đua và có thể đi về phía trước, bên trái và bên phải tại chân đế, 000
Nếu xe đang di chuyển về phía trước, các bit sẽ là 010 nếu chuyển tiếp và để nó sẽ là 110 vv ...

Làm cách nào để đặt bit và cách tôi có thể đọc lại để nhận các giá trị?Java Làm việc với các bit

+0

Lý do tôi đã quan tâm trong việc sử dụng phương pháp này là vì tôi sẽ được vận chuyển thông tin này trên mạng và mỗi bit được thực sự xảy ra để đếm. Tôi nghĩ rằng tôi sẽ phải sử dụng một byte toàn bộ để gửi dữ liệu đó là tốt vì tôi có thể lẻn thêm một số dữ liệu trong đó, tôi nghĩ rằng tôi sẽ đọc các liên kết trên bit masking. Nếu một số người có thể cho tôi một ví dụ về điều đó sẽ là tuyệt vời – Prospero

Trả lời

9

bit Nếu kích thước và tốc độ là quan trọng, sử dụng trong một byte. (Đọc các liên kết được đăng trong câu trả lời khác vì có các biến chứng không rõ ràng khi sử dụng và truyền các kiểu dữ liệu đã ký.)

Mã này cho tốc độ: đứng, trái, trái, phía trước, phải, và phải.

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 

Cũng lưu ý rằng trái và bên phải là loại trừ lẫn nhau, vì vậy có thể của nó để tạo ra một sự kết hợp bất hợp pháp. (7 = 111)

Nếu bạn thực sự có nghĩa là một thứ chỉ có thể di chuyển TRÁI, FORWARD hoặc RIGHT, thì bạn không cần cờ, chỉ cần enums.

Enum này có thể vận chuyển chỉ trong hai bit.

enum Direction{ 
    NONE, FORWARD, RIGHT, LEFT; 

} 


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

Hai bit cuối cùng trong enc sẽ trở thành:

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

Ít nhất bạn cần lưu trữ ba bit này là một trong số byte.

Đọc this tutorial về các toán tử bitwise để bắt đầu.

Chỉnh sửa: this page trên mặt nạ bit cũng có thể rất hữu ích.

3

Bạn nói ba trạng thái, nhưng bạn đã thực sự có sáu trạng thái: về phía trước, phía trước, trái, sang phải, trái, phải, đứng yên. Trừ khi chiếc xe đua của bạn không di chuyển ngang hàng, thì bạn đã có bốn chiếc.

Bạn thực sự cần sử dụng một enum cho việc này:

enum State { FORWARD, FORWARD_LEFT, FORWARD_RIGHT, STAND_STILL } 

Từ trái, phải và phía trước là loại trừ lẫn nhau, đây không phải là một sự phù hợp rất tốt cho một chương trình bit không quan trọng. Bạn sẽ nhận được vào tất cả các loại vấn đề nhất quán.

+2

Trừ khi bạn cần serialize đối tượng của bạn trên một phương tiện được mỗi byte đếm, sử dụng enums. Chúng dễ đọc hơn và có các tính năng cho phép bạn thực hiện các vòng lặp trên báo cáo trạng thái hoặc chuyển đổi. Ngay cả khi bạn cần một định dạng nén, nó sẽ dễ dàng hơn để sử dụng enums và sau đó xây dựng các phiên bản nén khi cần thiết. – unholysampler

+0

Do đó, tránh sự cố nhất quán cho đến khi hủy tuần tự hóa. Cảm ơn, unholysampler. –

+0

Tôi thực sự đang sắp xếp trên một phương tiện mà mỗi bit đếm, đó là lỗi của tôi vì không rõ ràng. – Prospero

2

Trong java.util có một lớp được gọi là BitSet làm cho thao tác bit rất đơn giản.

Trong trường hợp của bạn, bạn có thể tạo BitSet có kích thước 3 và sau đó sử dụng các phương thức get() và set() để đặt kiểm tra các bit.

10

tôi sẽ đề nghị sử dụng BitSet cùng với enum của

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

Cảm ơn bạn đã trả lời. Trân trọng câu trả lời của KarlP đều đáng để đánh dấu. Tôi thực tế đã sử dụng ví dụ của bạn trong mã. – Prospero

+0

http://indianjavalearners.blogspot.in/p/blog-page.html khi chúng tôi sử dụng enum –

Các vấn đề liên quan