Cosa fa value & 0xff in Java?


98

Ho il seguente codice Java:

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

Il risultato è 254 quando viene stampato, ma non ho idea di come funzioni questo codice. Se l' &operatore è semplicemente bit per bit, perché non risulta in un byte e invece in un numero intero?


Copio il codice in Eclipse. Mi avvisa "Tipo non corrispondente: impossibile convertire da int a byte". Dovrebbe cambiare in valore int = 0xfe;
Ben Cheng

1
@BenCheng dovrebbe esserebyte value = (byte) 0xfe;
Bek

Risposte:


171

Viene impostato resultsul valore (senza segno) risultante dall'inserimento degli 8 bit di valuenegli 8 bit più bassi di result.

Il motivo per cui è necessario qualcosa di simile è che byteè un tipo firmato in Java. Se hai appena scritto:

int result = value;

quindi resultfinirebbe con il valore ff ff ff feinvece di 00 00 00 fe. Un'ulteriore sottigliezza è che &è definito per operare solo sui intvalori 1 , quindi ciò che accade è:

  1. valueviene promosso a int( ff ff ff fe).
  2. 0xffè un intletterale ( 00 00 00 ff).
  3. La &viene applicato per ottenere il valore desiderato per result.

(Il punto è che la conversione a intavviene prima dell'applicazione &dell'operatore.)

1 Beh, non proprio. L' &operatore funziona anche sui longvalori, se uno degli operandi è un file long. Ma non su byte. Vedere la specifica del linguaggio Java, sezioni 15.22.1 e 5.6.2 .


Cosa significa la x in quella notazione? x non è un numero o un numero esadecimale?
Callat

3
@KazRodgers - Il prefisso 0x(or 0X) dice a Java che il valore letterale intero che segue deve essere interpretato come esadecimale (base 16). Java supporta anche un semplice 0prefisso per i letterali ottali e un prefisso 0b(or 0B) per i letterali binari. Vedere la specifica del linguaggio Java per ulteriori informazioni in valori letterali interi.
Ted Hopp

Il letterale che segue? Quindi, ad esempio, se avessi 0x3fa. Il 3fa è la parte che viene tradotta in un numero letterale e 0x sta annotando "questo è un numero esadecimale"? @TedHopp?
Callat

1
@KazRodgers - Esattamente. Nota che 0xo 0bda solo (senza alcuna cifra successiva) è una sintassi illegale in Java.
Ted Hopp

1
@DmitryMinkovsky - Il modello di bit esadecimale fea 8 bit, il complemento a due corrisponde al valore decimale −2. Per preservare il valore, Integer.valueOf(byte)sarebbe necessario produrre ff ff ff fe(−2 a 32 bit, complemento a due), non 00 00 00 fe(valore decimale 254). Questa trasformazione (da un bytevalore fea un intvalore ff ff ff fe) è nota come estensione del segno e fa parte della specifica del linguaggio Java. Lo scopo di value & 0xffè annullare l'estensione del segno (cioè simulare l'estensione zero, qualcosa che Java non ha).
Ted Hopp

57

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

Il valore letterale esadecimale 0xFF è un int uguale (255). Java rappresenta int come 32 bit. Sembra questo in binario:

00000000 00000000 00000000 11111111

Quando esegui un AND un po 'saggio con questo valore (255) su qualsiasi numero, maschererà (renderà ZERO) tutti tranne gli 8 bit più bassi del numero (saranno così com'è).

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

& è qualcosa come% ma non proprio .

E perché 0xff? questo in ((potenza di 2) - 1). All ((power of 2) - 1) (eg 7, 255 ...) si comporterà in modo simile all'operatore%.

Quindi
in binario, 0 è, tutti zeri e 255 ha questo aspetto:

00000000 00000000 00000000 11111111

E -1 assomiglia a questo

11111111 11111111 11111111 11111111

Quando si esegue un AND bit per bit di 0xFF e qualsiasi valore compreso tra 0 e 255, il risultato è esattamente lo stesso del valore. E se qualsiasi valore superiore a 255, il risultato sarà comunque compreso tra 0 e 255.

Tuttavia, se lo fai:

-1 & 0xFF

ottieni

00000000 00000000 00000000 11111111, che NON è uguale al valore originale di -1 ( 11111111è 255 in decimale).


Qualche altra manipolazione di bit: (non correlata alla domanda)

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

Verificare che un bit particolare sia impostato (1) o meno (0)

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

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

Imposta (1) un bit particolare

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

ReSet (0) un particolare bit

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

XOR

Tieni presente che se esegui due volte l'operazione XOR, risulterà lo stesso valore.

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

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

Un'altra logica con XOR è

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

Quanto sopra è utile per scambiare due variabili senza temp come sotto

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

O

a ^= b ^= a ^= b;

Hanno anche un'occhiata @ manipolazione Bit stackoverflow.com/questions/13422259/...
Kanagavelu Sugumar


4

Aiuta a ridurre molti codici. Occasionalmente viene utilizzato nei valori RGB che consistono di 8 bit.

dove 0xff significa 24 (0) e 8 (1) come00000000 00000000 00000000 11111111

Maschera efficacemente la variabile in modo da lasciare solo il valore negli ultimi 8 bit e ignora tutti gli altri bit

È visto nella maggior parte dei casi come quando si tenta di trasformare i valori di colore da un formato speciale a valori RGB standard (che è lungo 8 bit).

Grande spiegazione Vedi qui


0

Nel sistema di formato a 32 bit il valore esadecimale 0xffrappresenta 00000000000000000000000011111111che è 255(15*16^1+15*16^0)in decimale. e l'operatore & bit per bit maschera gli stessi 8 bit più a destra del primo operando.


puoi spiegare un po 'di più.
ashishdhiman 2007
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.