2012-03-30 18 views
7

Trong đoạn sau xem xét thay thế dòng 8 với nhận xét tương đươngAnding với 0xff, làm rõ cần

1. private static String ipToText(byte[] ip) { 
2. StringBuffer result = new StringBuffer(); 
3. 
4. for (int i = 0; i < ip.length; i++) { 
5.  if (i > 0) 
6.   result.append("."); 
7. 
8.  result.append(ip[i]); // compare with result.append(0xff & ip[i]); 
9. } 
10. 
11.  return result.toString(); 
12. } 

.equals() kiểm tra khẳng định rằng việc thêm 0xff không thay đổi bất cứ điều gì. Có lý do nào cho mặt nạ này được áp dụng không?

+0

Tôi không chắc chắn, nhưng có vẻ như chuyển đổi thành byte chưa ký. – Osw

Trả lời

16

byte trong Java là một số giữa − 128 và 127 (chưa ký, giống như mọi số nguyên trong Java (ngoại trừ char nếu bạn muốn đếm)). Bởi anding với 0xff bạn đang buộc nó phải là một tích cực int từ 0 đến 255.

Nó hoạt động vì Java sẽ thực hiện một chuyển đổi mở rộng để int, sử dụng phần mở rộng dấu, vì vậy thay vì phủ định byte bạn sẽ có một tiêu cực int. Masking với 0xff sẽ chỉ để lại 8 bit thấp hơn, do đó làm cho số dương một lần nữa (và những gì bạn ban đầu dự định).

Có thể bạn không để ý sự khác biệt bởi vì bạn thử nghiệm với một byte[] chỉ với giá trị nhỏ hơn 128.

ví dụ nhỏ:

public class A { 
    public static void main(String[] args) { 
     int[] ip = new int[] {192, 168, 101, 23}; 
     byte[] ipb = new byte[4]; 
     for (int i =0; i < 4; i++) { 
      ipb[i] = (byte)ip[i]; 
     } 

     for (int i =0; i < 4; i++) { 
      System.out.println("Byte: " + ipb[i] + ", And: " + (0xff & ipb[i])); 
     } 
    } 
} 

này in

Byte: -64, And: 192 
Byte: -88, And: 168 
Byte: 101, And: 101 
Byte: 23, And: 23 

hiển thị sự khác biệt giữa những gì trong số byte, những gì đã đi vào byte khi nó vẫn là một int và thứ gì kết quả của hoạt động & là.

+0

Re: "Điều này là bởi vì' 0xff' là loại 'int', do đó byte được thăng lên' int' là tốt ": Kiểu thăng hạng thành' int' sẽ thực sự xảy ra ngay cả khi cả hai đối số có kiểu 'byte' ; Java không có toán tử '&' riêng biệt cho 'byte'. (Và trong phiên bản không có '&', loại khuyến mãi để 'int' sẽ xảy ra trong quá trình phân giải quá tải, vì' StringBuffer' không có phương thức 'append (byte)'.) – ruakh

+0

Thật vậy, bạn nói đúng. Phần liên quan rõ ràng là chúng ta mở rộng mở rộng ký hiệu thành 'int' trong mọi trường hợp và bằng cách che dấu 8 bit thấp hơn, chúng ta có thể buộc nó trở thành một byte chưa ký một lần nữa :) – Joey

1

Trong ví dụ này, tôi không thấy nó sẽ tạo ra bất kỳ sự khác biệt nào. Bạn đang và đang sử dụng 0xff với một byte. Một byte theo định nghĩa có 8 bit, và thêm mặt nạ ra khỏi 8 bit cuối cùng. Vì vậy, bạn đang dùng 8/8 cuối cùng, điều đó sẽ không làm gì cả.

Và với 0xff sẽ có ý nghĩa nếu điều bạn đang làm và với nó lớn hơn một byte, ngắn hoặc int hoặc bất kỳ thứ gì.

+0

Hoặc chỉ lớn hơn 127;) – Joey

+0

Rất tiếc, tôi thú nhận, tôi đã hiểu sai câu hỏi. Tôi đã nghĩ rằng nó đã đưa nó trở lại vào một mảng byte, tôi đã không bắt được rằng nó đã chuyển đổi nó thành văn bản. – Jay

1

Điều này chỉ nên tạo sự khác biệt nếu có byte âm. & 0xff thường được sử dụng để diễn giải một byte là chưa ký.

3

Khi bạn đã làm việc với một mảng byte ở đây và bạn đang thực hiện thao tác bitwise, bạn có thể bỏ qua cách Java xử lý tất cả byte như đã ký. Sau khi tất cả, bạn đang làm việc trên mức bit bây giờ, và không có những điều như là "ký" hoặc "unsigned" giá trị trên mức độ bit.

Mặt nạ giá trị 8 bit (một byte) với tất cả 1 chỉ là một sự lãng phí chu kỳ, vì không có gì sẽ bị che khuất. Một bitewise AND sẽ trả về một bit đúng nếu cả hai bit được so sánh là true, do đó nếu mặt nạ chứa tất cả 1, thì bạn chắc chắn rằng tất cả các bit của giá trị được che sẽ không thay đổi sau thao tác AND.

Hãy xem xét các ví dụ sau:

Mask off the upper nibble: 
    0110 1010 
AND 0000 1111 (0x0F) 
    = 0000 1010
Mask off the lower nibble: 
    0110 1010 
AND 1111 0000 (0xF0) 
    = 0110 0000
Mask off... Eh, nothing: 
    0110 1010 
AND 1111 1111 (0xFF) 
    = 0110 1010 

Tất nhiên, nếu bạn đang làm việc với một int thổi đầy đủ ở đây, bạn sẽ nhận được kết quả ở những người khác đã nói: Bạn' d "force" int là tương đương với một byte unsigned.

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