Trong Java, tôi có thể xác định một hằng số nguyên ở định dạng nhị phân không?


85

Tương tự như cách bạn có thể xác định một hằng số nguyên trong hệ thập lục phân hoặc bát phân, tôi có thể làm điều đó trong hệ nhị phân không?

Tôi thừa nhận đây là một câu hỏi thực sự dễ (và ngu ngốc). Các tìm kiếm trên google của tôi đang trống.


2
Chỉ FYI, trong hầu hết mọi ngôn ngữ lập trình, thành ngữ là viết các hằng số nhị phân dưới dạng hex, chứ không phải chuỗi nhị phân thực tế.
abyx

3
Đúng, nhưng tôi tưởng tượng đó là bởi vì hex là thứ gần nhất có sẵn, không phải vì có gì đó sai với hệ nhị phân. Trong các ngôn ngữ tôi đã sử dụng hỗ trợ các ký tự nhị phân, tôi không nghĩ quy ước là bỏ qua tính năng này.
Ken,


Năm 2017: câu trả lời được chấp nhận phải là câu trả lời do Russ cung cấp. Xem: stackoverflow.com/a/1692932/716079
Lourenco

Câu trả lời:


65

Vì vậy, với việc phát hành Java SE 7, ký hiệu nhị phân trở thành tiêu chuẩn. Cú pháp khá đơn giản và rõ ràng nếu bạn hiểu rõ về hệ nhị phân:

byte fourTimesThree = 0b1100;
byte data = 0b0000110011;
short number = 0b111111111111111; 
int overflow = 0b10101010101010101010101010101011;
long bow = 0b101010101010101010101010101010111L;

Và đặc biệt ở điểm khai báo các biến cấp lớp dưới dạng mã nhị phân, hoàn toàn không có vấn đề gì khi khởi tạo một biến tĩnh bằng cách sử dụng ký hiệu nhị phân:

public static final int thingy = 0b0101;

Chỉ cần cẩn thận để không làm tràn các số với quá nhiều dữ liệu, nếu không bạn sẽ gặp lỗi trình biên dịch:

byte data = 0b1100110011; // Type mismatch: cannot convert from int to byte

Bây giờ, nếu bạn thực sự muốn trở nên lạ mắt, bạn có thể kết hợp tính năng mới gọn gàng khác trong Java 7 được gọi là ký tự số với dấu gạch dưới. Hãy xem các ví dụ lạ mắt về ký hiệu nhị phân với dấu gạch dưới theo nghĩa đen:

int overflow = 0b1010_1010_1010_1010_1010_1010_1010_1011;
long bow = 0b1__01010101__01010101__01010101__01010111L;

Bây giờ nó không đẹp và sạch sẽ, chưa kể là rất dễ đọc?

Tôi đã lấy những đoạn mã này từ một bài báo nhỏ tôi đã viết về chủ đề này tại TheServerSide. Vui lòng kiểm tra nó để biết thêm chi tiết:

Java 7 và ký hiệu nhị phân: Làm chủ kỳ thi lập trình viên Java OCP (OCPJP)


3
Tại sao dữ liệu byte của bạn = 0b0000110011; có 10 bit? Tôi mới lập trình nhưng tôi nghĩ nó phải giống như 0b00110011 để phù hợp với 8 bit của kiểu dữ liệu byte.
Mike

1
Đối với bất kỳ ai cũng thắc mắc giống như Mike, đó là bởi vì trình biên dịch chuyển đổi nó thành số mà nó đại diện - bạn có thể có hàng chục số 0 đứng đầu và chúng sẽ không ảnh hưởng đến giá trị thực. Quá trình biên dịch về cơ bản giống như khi bạn viết một số thập phân ở đó.
Luke Briggs,

1
theo định nghĩa kiểu nguyên thủy byte có thể lưu trữ 256 số từ -128 đến 127 (-128 đến -1 & 0 đến 127). Nhưng làm thế nào để biểu diễn -128 bằng cách sử dụng một chữ nhị phân. ví dụ: byte b = -0b1111111; biểu thị -127 nhưng còn -128 thì sao?
nirmalsingh

152

Trong Java 7:

int i = 0b10101010;

Không có ký tự nhị phân trong các phiên bản Java cũ hơn (xem các câu trả lời khác để biết các lựa chọn thay thế).


33
Tôi cũng thích đến thời điểm ra có thể có _nhân vật để làm cho trình tự dễ đọc hơn: int i = 0b1010_1010_0011;
user12345613

@Russ 0b biểu thị điều gì ở đây? Tính năng này được gọi là gì trong Java 7?
Geek

1
0b biểu thị nhị phân. Tính năng này được gọi là các chữ nhị phân: docs.oracle.com/javase/7/docs/technotes/guides/language/…
Russ Hayward

1
Yêu thích cách biểu diễn dữ liệu nhị phân mới này. Biểu diễn chuỗi sẽ rất khó đọc. Hãy xem sự khác biệt của câu trả lời được chấp nhận và câu trả lời từ "@ user12345613". +1 cho anh ấy.
Marcello de Sales

54

Không có ký tự nhị phân trong Java, nhưng tôi cho rằng bạn có thể làm điều này (mặc dù tôi không hiểu rõ vấn đề):

int a = Integer.parseInt("10101010", 2);

1
Trong số các cách sử dụng khác, mô hình xáo trộn để phân loại đường thẳng và đa giác được chỉ định dưới dạng số nguyên trong một số thư viện đồ họa phổ biến. Sử dụng parseInt hoặc parseShort cho phép nhà phát triển dễ dàng hình dung mẫu.
charstar

5
Kể từ Java 7, câu trả lời của Russ Hayward là câu trả lời chính xác. Trước Java 7, bạn có thể sử dụng một công cụ trực tuyến hoặc máy tính yêu thích của mình để chuyển đổi nhị phân sang một trong các ký hiệu được các phiên bản Java cũ công nhận (bát phân, thập phân hoặc thập lục phân). Nếu sử dụng một cơ số khác, một chú thích mô tả chứa biểu diễn nhị phân có thể được đặt ở phần khai báo để làm rõ giá trị cho người đọc.
Jason C

Đây là một dung dịch khá bẩn, phải không? Bạn chỉ lấy 16 byte để đại diện cho 1 byte (không tính đối số thứ hai và chuyển đổi). Tất nhiên, trừ khi trình biên dịch tối ưu hóa điều này, điều mà tôi nghi ngờ.
Tomáš Zato - Phục hồi Monica

@ TomášZato: Đúng vậy, nhưng bạn sẽ đề xuất giải pháp nào vì ngôn ngữ không hỗ trợ các ký tự nhị phân khi tôi viết câu trả lời này? Russ Hayward nên có câu trả lời được chấp nhận ngay bây giờ.
Ed S.

Tôi sẽ đề nghị từ bỏ sự thoải mái và sử dụng số nguyên. Trong bản thân định nghĩa biến thì không sao, nhưng câu trả lời này có thể thúc đẩy người dùng sử dụng cách tiếp cận này cho các vòng lặp, v.v. Và nói chung, tôi nghĩ lập trình viên nên cố gắng từ bỏ sự thoải mái của mình cho một số hiệu suất.
Tomáš Zato - Phục hồi Monica

18

Câu trả lời từ Ed Swangren

public final static long mask12 = 
  Long.parseLong("00000000000000000000100000000000", 2);

hoạt động tốt. Tôi đã sử dụng longthay vì intvà thêm các bổ ngữ để làm rõ cách sử dụng có thể có như một mặt nạ bit. Tuy nhiên, có hai điểm bất tiện với cách tiếp cận này.

  1. Việc nhập trực tiếp tất cả các số 0 đó dễ bị lỗi
  2. Kết quả không có sẵn ở định dạng thập phân hoặc hex tại thời điểm phát triển

Tôi có thể đề xuất cách tiếp cận thay thế

public final static long mask12 = 1L << 12;

Biểu thức này cho thấy rõ ràng rằng bit thứ 12 là 1 (số đếm bắt đầu từ 0, từ phải sang trái); và khi bạn di con trỏ chuột, chú giải công cụ

long YourClassName.mask12 = 4096 [0x1000]

xuất hiện trong Eclipse. Bạn có thể xác định các hằng số phức tạp hơn như:

public final static long maskForSomething = mask12 | mask3 | mask0;

hoặc rõ ràng

public final static long maskForSomething = (1L<<12)|(1L<<3)|(1L<<0);

Giá trị của biến maskForSomethingsẽ vẫn có sẵn trong Eclipse tại thời điểm phát triển.


Giải pháp tuyệt vời! (public final static long mask12 = 1L << 12;)
Jyro117

17

Sử dụng hằng số nhị phân để tạo mặt nạ

Khai báo các hằng số:

public static final int FLAG_A = 1 << 0;
public static final int FLAG_B = 1 << 1;
public static final int FLAG_C = 1 << 2;
public static final int FLAG_D = 1 << 3;

và sử dụng chúng

if( (value & ( FLAG_B | FLAG_D )) != 0){
    // value has set FLAG_B and FLAG_D
}

12

Tìm kiếm "cú pháp ký tự Java" trên Google và bạn tìm thấy một số mục nhập.

Có một cú pháp bát phân (bắt đầu số của bạn bằng 0), cú pháp thập phân và cú pháp thập lục phân với tiền tố "0x". Nhưng không có cú pháp cho ký hiệu nhị phân.

Vài ví dụ:

int i = 0xcafe ; // hexadecimal case
int j = 045 ;    // octal case
int l = 42 ;     // decimal case

1
Điều này không trả lời câu hỏi.
Michael McQuade

Năm 2017: May mắn thay có ký hiệu cho biểu diễn nhị phân. Nó bắt đầu bằng "0b". Ví dụ: byte b = 0b01000001(để dễ đọc hơn byte b = 0b0100_0001).
Lourenco

2

Nếu bạn muốn lộn xộn với nhiều nhị phân, bạn có thể xác định một số hằng số:

public static final int BIT_0 = 0x00000001;
public static final int BIT_1 = 0x00000002;

Vân vân.

hoặc là

public static final int B_00000001 = 0x00000001;
public static final int B_00000010 = 0x00000002;
public static final int B_00000100 = 0x00000004;

0

Câu trả lời hơi khó xử hơn một chút:

public class Main {

    public static void main(String[] args) {
        byte b = Byte.parseByte("10", 2);
        Byte bb = new Byte(b);
        System.out.println("bb should be 2, value is \"" + bb.intValue() + "\"" );
    }

}

kết quả đầu ra [java] bb phải là 2, giá trị là "2"

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.