Giá trị & 0xff làm gì trong Java?


98

Tôi có mã Java sau:

byte value = 0xfe; // corresponds to -2 (signed) and 254 (unsigned)
int result = value & 0xff;

Kết quả là 254 khi được in, nhưng tôi không biết mã này hoạt động như thế nào. Nếu &toán tử chỉ đơn giản là bitwise, thì tại sao nó không dẫn đến một byte mà thay vào đó là một số nguyên?


Tôi sao chép mã vào Eclipse. Nó cảnh báo tôi "Loại không khớp: không thể chuyển đổi từ int sang byte". Nếu nó thay đổi thành int value = 0xfe;
Ben Cheng

1
@BenCheng nên đượcbyte value = (byte) 0xfe;
Bek

Câu trả lời:


171

Nó đặt resultthành giá trị (không dấu) do đặt 8 bit valuetrong 8 bit thấp nhất của result.

Lý do một cái gì đó như thế này là cần thiết bytelà một kiểu có dấu trong Java. Nếu bạn vừa viết:

int result = value;

sau đó resultsẽ kết thúc bằng giá trị ff ff ff fethay vì 00 00 00 fe. Một điều tinh tế hơn nữa là giá trị &được định nghĩa chỉ hoạt động trên intcác giá trị 1 , vì vậy điều xảy ra là:

  1. valueđược thăng cấp thành một int( ff ff ff fe).
  2. 0xfflà một intnghĩa đen ( 00 00 00 ff).
  3. Các &được áp dụng để mang lại giá trị mong muốn cho result.

(Điểm có ích là chuyển đổi intxảy ra trước khi các &nhà điều hành được áp dụng.)

1 Chà, không hoàn toàn. Các &nhà điều hành hoạt động trên longcác giá trị là tốt, nếu một trong hai toán hạng là một long. Nhưng không phải trên byte. Xem Đặc tả ngôn ngữ Java, phần 15.22.15.6.2 .


Dấu x có nghĩa là gì trong ký hiệu đó? x không phải là một số hay một số hex?
Callat

3
@KazRodgers - Tiền tố 0x(hoặc 0X) cho Java biết rằng ký tự số nguyên theo sau phải được hiểu là hex (cơ số 16). Java cũng hỗ trợ một 0tiền tố trần cho các ký tự bát phân và một tiền tố 0b(hoặc 0B) cho các ký tự nhị phân. Xem Đặc tả ngôn ngữ Java để biết thêm thông tin trong các ký tự số nguyên.
Ted Hopp

Nghĩa đen sau đó? Vì vậy, ví dụ nếu tôi có 0x3fa. 3fa là phần được dịch thành một số theo nghĩa đen và 0x được chú ý "đây là một số hex"? @TedHopp?
Callat

1
@KazRodgers - Chính xác. Lưu ý rằng 0xhoặc 0bbản thân nó (không có bất kỳ chữ số nào theo sau) là cú pháp bất hợp pháp trong Java.
Ted Hopp

1
@DmitryMinkovsky - Mẫu bit hex fetrong 8 bit, phần bù của hai tương ứng với giá trị thập phân −2. Để bảo toàn giá trị, Integer.valueOf(byte)sẽ cần tạo ra ff ff ff fe(−2 trong 32-bit, phần bù của hai), không phải 00 00 00 fe(giá trị thập phân 254). Sự chuyển đổi này (từ một bytegiá trị fesang một intgiá trị ff ff ff fe) được gọi là phần mở rộng dấu hiệu và là một phần của đặc tả ngôn ngữ Java. Mục đích của value & 0xfflà để hoàn tác phần mở rộng dấu hiệu (tức là, để mô phỏng phần mở rộng bằng không, thứ mà Java không có).
Ted Hopp

57

Từ http://www.coderanch.com/t/236675/java-programmer-SCJP/certification/xff

Chữ thập lục phân 0xFF là một int bằng (255). Java biểu diễn int là 32 bit. Nó trông như thế này trong hệ nhị phân:

00000000 00000000 00000000 11111111

Khi bạn thực hiện một chút khôn ngoan VÀ với giá trị này (255) trên bất kỳ số nào, nó sẽ che dấu (tạo số KHÔNG) tất cả trừ 8 bit thấp nhất của số (sẽ là nguyên trạng).

... 01100100 00000101 & ...00000000 11111111 = 00000000 00000101

& là một cái gì đó giống như% nhưng không thực sự .

Và tại sao 0xff? này trong ((lũy thừa của 2) - 1). Tất cả ((lũy thừa của 2) - 1) (ví dụ: 7, 255 ...) sẽ hoạt động giống như toán tử%.

Sau đó,
Trong hệ nhị phân, 0 là, tất cả các số không và 255 trông giống như sau:

00000000 00000000 00000000 11111111

Và -1 trông như thế này

11111111 11111111 11111111 11111111

Khi bạn thực hiện theo bitwise AND của 0xFF và bất kỳ giá trị nào từ 0 đến 255, kết quả sẽ giống hệt như giá trị. Và nếu bất kỳ giá trị nào cao hơn 255 thì kết quả sẽ nằm trong khoảng 0-255.

Tuy nhiên, nếu bạn làm:

-1 & 0xFF

bạn lấy

00000000 00000000 00000000 11111111, KHÔNG bằng giá trị ban đầu của -1 ( 11111111là 255 trong hệ thập phân).


Thêm một vài thao tác: (Không liên quan đến câu hỏi)

X >> 1 = X/2
X << 1 = 2X

Kiểm tra bất kỳ bit cụ thể nào được đặt (1) hay không (0) sau đó

 int thirdBitTobeChecked =   1 << 2   (...0000100)
 int onWhichThisHasTobeTested = 5     (.......101)

 int isBitSet = onWhichThisHasTobeTested  & thirdBitTobeChecked;
 if(isBitSet > 0) {
  //Third Bit is set to 1 
 } 

Đặt (1) một bit cụ thể

 int thirdBitTobeSet =   1 << 2    (...0000100)
 int onWhichThisHasTobeSet = 2     (.......010)
 onWhichThisHasTobeSet |= thirdBitTobeSet;

Đặt lại (0) một bit cụ thể

int thirdBitTobeReSet =   ~(1 << 2)  ; //(...1111011)
int onWhichThisHasTobeReSet = 6      ;//(.....000110)
onWhichThisHasTobeReSet &= thirdBitTobeReSet;

XOR

Chỉ cần lưu ý rằng nếu bạn thực hiện thao tác XOR hai lần, kết quả sẽ có cùng giá trị.

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

byte encryptedVal  =  toBeEncrypted ^ salt == 0110 1101
byte decryptedVal  =  encryptedVal  ^ salt == 0010 0110 == toBeEncrypted :)

Một logic nữa với XOR là

if     A (XOR) B == C (salt)
then   C (XOR) B == A
       C (XOR) A == B

Ở trên rất hữu ích để hoán đổi hai biến mà không cần tạm thời như bên dưới

a = a ^ b; b = a ^ b; a = a ^ b;

HOẶC LÀ

a ^= b ^= a ^= b;

Cũng có cái nhìn @ Bit thao tác stackoverflow.com/questions/13422259/…
Kanagavelu Sugumar


4

Nó giúp giảm thiểu rất nhiều mã. Nó đôi khi được sử dụng trong các giá trị RGB bao gồm 8bit.

trong đó 0xff có nghĩa là 24 (0) và 8 (1) như00000000 00000000 00000000 11111111

Nó che dấu biến một cách hiệu quả nên nó chỉ để lại giá trị trong 8 bit cuối cùng và bỏ qua tất cả các bit còn lại

Nó được nhìn thấy nhiều nhất trong các trường hợp như khi cố gắng chuyển đổi các giá trị màu từ một định dạng đặc biệt thành các giá trị RGB tiêu chuẩn (dài 8 bit).

Giải thích tuyệt vời Xem tại đây


0

Trong hệ thống định dạng 32 bit, giá trị thập lục phân 0xffbiểu thị giá trị 00000000000000000000000011111111đó 255(15*16^1+15*16^0)ở dạng thập phân. và toán tử bitwise & che dấu 8 bit bên phải giống như trong toán hạng đầu tiên.


bạn có thể giải thích thêm một chút.
ashishdhiman2007 19/04/17
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.