Apa yang dilakukan value & 0xff di Java?

101

Saya memiliki kode Java berikut:

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

Hasilnya adalah 254 saat dicetak, tetapi saya tidak tahu cara kerja kode ini. Jika &operatornya hanya bitwise, lalu mengapa tidak menghasilkan byte melainkan integer?

dagronlund.dll
sumber
Saya menyalin kode ke Eclipse. Ini memperingatkan saya "Ketik ketidakcocokan: tidak dapat mengkonversi dari int ke byte". Haruskah itu berubah menjadi nilai int = 0xfe;
Ben Cheng
1
@BenCharusbyte value = (byte) 0xfe;
Bek

Jawaban:

173

Ini menetapkan resultke nilai (unsigned) yang dihasilkan dari menempatkan 8 bit valuedi 8 bit terendah result.

Alasan mengapa hal seperti ini diperlukan adalah karena bytetipe yang ditandatangani di Java. Jika Anda baru saja menulis:

int result = value;

maka resultakan berakhir dengan nilai, ff ff ff febukan 00 00 00 fe. Kehalusan lebih lanjut adalah bahwa &didefinisikan untuk beroperasi hanya pada intnilai 1 , jadi yang terjadi adalah:

  1. valuedipromosikan menjadi int( ff ff ff fe).
  2. 0xffadalah intliteral ( 00 00 00 ff).
  3. The &diterapkan untuk menghasilkan nilai yang diinginkan untuk result.

(Intinya adalah bahwa konversi ke intterjadi sebelum para &operator diterapkan.)

1 Yah, kurang tepat. The &Operator bekerja pada longnilai-nilai juga, jika salah satu operan adalah long. Tapi tidak byte. Lihat Spesifikasi Bahasa Java, bagian 15.22.1 dan 5.6.2 .

Ted Hopp
sumber
Apa arti x dalam notasi itu? x bukan angka atau angka hex?
Hubungi
3
@KazRodgers - Awalan 0x(atau 0X) memberi tahu Java bahwa literal integer yang mengikuti harus ditafsirkan sebagai hex (basis 16). Java juga mendukung 0awalan kosong untuk literal oktal dan awalan 0b(atau 0B) untuk literal biner. Lihat Spesifikasi Bahasa Java untuk info lebih lanjut dalam literal integer.
Ted Hopp
Kata literal yang mengikuti? Jadi misalnya jika saya punya 0x3fa. 3fa adalah bagian yang diterjemahkan ke dalam angka literal dan 0x menunjukkan "ini adalah nomor hex"? @Tedopp?
Hubungi
1
@KazRgers - Tepat. Perhatikan bahwa 0xatau 0bdengan sendirinya (tanpa digit setelahnya) adalah sintaks ilegal di Java.
Ted Hopp
1
@DmitryMinkovsky - Pola hex bit fedalam 8-bit, komplemen dua sesuai dengan nilai desimal −2. Untuk mempertahankan nilai, Integer.valueOf(byte)perlu menghasilkan ff ff ff fe(−2 dalam 32-bit, komplemen dua), bukan 00 00 00 fe(nilai desimal 254). Transformasi ini (dari bytenilai femenjadi intnilai ff ff ff fe) dikenal sebagai ekstensi tanda dan merupakan bagian dari spesifikasi bahasa Java. Tujuannya value & 0xffadalah untuk membatalkan ekstensi tanda (yaitu, untuk mensimulasikan ekstensi nol, sesuatu yang tidak dimiliki Java).
Ted Hopp
57

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

Hex literal 0xFF adalah int yang sama (255). Java mewakili int sebagai 32 bit. Ini terlihat seperti ini dalam biner:

00000000 00000000 00000000 11111111

Ketika Anda melakukan sedikit bijaksana AND dengan nilai ini (255) pada nomor apapun, itu akan menutupi (membuat NOL) semua kecuali 8 bit terendah dari nomor tersebut (akan seperti apa adanya).

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

& adalah sesuatu seperti% tapi tidak juga .

Dan mengapa 0xff? ini di ((kekuatan 2) - 1). Semua ((pangkat 2) - 1) (mis. 7, 255 ...) akan berperilaku seperti operator%.

Kemudian
Dalam biner, 0 adalah, semua nol, dan 255 terlihat seperti ini:

00000000 00000000 00000000 11111111

Dan -1 terlihat seperti ini

11111111 11111111 11111111 11111111

Saat Anda melakukan bitwise AND dari 0xFF dan nilai apa pun dari 0 hingga 255, hasilnya sama persis dengan nilainya. Dan jika ada nilai yang lebih tinggi dari 255 tetap hasilnya akan berada dalam 0-255.

Namun, jika Anda melakukannya:

-1 & 0xFF

Anda mendapatkan

00000000 00000000 00000000 11111111, yang TIDAK sama dengan nilai asli -1 ( 11111111adalah 255 dalam desimal).


Manipulasi bit lagi: (Tidak terkait dengan pertanyaan)

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

Periksa apakah bit tertentu disetel (1) atau tidak (0) lalu

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

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

Atur (1) bit tertentu

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

Setel ulang (0) bit tertentu

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

XOR

Perhatikan saja bahwa jika Anda melakukan operasi XOR dua kali, akan menghasilkan nilai yang sama.

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

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

Satu lagi logika dengan XOR adalah

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

Di atas berguna untuk menukar dua variabel tanpa suhu seperti di bawah ini

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

ATAU

a ^= b ^= a ^= b;
Kanagavelu Sugumar
sumber
Lihat juga @ Manipulasi bit stackoverflow.com/questions/13422259/…
Kanagavelu Sugumar
5

Ini membantu mengurangi banyak kode. Ini kadang-kadang digunakan dalam nilai RGB yang terdiri dari 8 bit.

di mana 0xff berarti 24 (0) dan 8 (1) suka00000000 00000000 00000000 11111111

Ini secara efektif menutupi variabel sehingga hanya menyisakan nilai dalam 8 bit terakhir, dan mengabaikan semua bit lainnya

Ini terlihat sebagian besar dalam kasus seperti ketika mencoba mengubah nilai warna dari format khusus ke nilai RGB standar (yang panjangnya 8 bit).

Penjelasan Hebat Lihat di sini

AndroidGeek
sumber
0

Dalam sistem 32 bit format nilai heksadesimal 0xffmewakili 00000000000000000000000011111111yang 255(15*16^1+15*16^0)dalam desimal. dan bitwise & operator menutupi 8 bit paling kanan yang sama seperti pada operan pertama.

kumar manish
sumber
bisakah Anda menjelaskan lebih banyak.
ashishdhiman2007