¿Qué hacen value & 0xff en Java?


98

Tengo el siguiente código Java:

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

El resultado es 254 cuando se imprime, pero no tengo idea de cómo funciona este código. Si el &operador es simplemente bit a bit, ¿por qué no da como resultado un byte y, en cambio, un entero?


Copio el código a Eclipse. Me advierte "No coinciden los tipos: no se puede convertir de int a byte". ¿Debería cambiar a int value = 0xfe;
— Ben Cheng

1
@BenCheng debería serbyte value = (byte) 0xfe;
— Bek

Respuestas:


171

Se establece resulten el valor (sin signo) resultante de colocar los 8 bits de valueen los 8 bits más bajos de result.

La razón por la que algo como esto es necesario es que bytees un tipo firmado en Java. Si acaba de escribir:

int result = value;

luego resultterminaría con el valor en ff ff ff felugar de 00 00 00 fe. Una sutileza adicional es que &está definido para operar solo en los intvalores 1 , por lo que lo que sucede es:

  1. valuese promueve a int( ff ff ff fe).
  2. 0xffes un intliteral ( 00 00 00 ff).
  3. Se &aplica para obtener el valor deseado result.

(El punto es que la conversión intocurre antes de& que se aplique el operador).

1 Bueno, no del todo. El &operador también trabaja con longvalores, si alguno de los operandos es un long. Pero no en byte. Consulte la Especificación del lenguaje Java, secciones 15.22.1 y 5.6.2 .


¿Qué significa la x en esa notación? ¿x no es un número o un número hexadecimal?
— Llamado

3
@KazRodgers: el prefijo 0x(o 0X) le dice a Java que el literal entero que sigue debe interpretarse como hexadecimal (base 16). Java también admite un 0prefijo simple para literales octales y un prefijo 0b(o 0B) para literales binarios. Consulte la Especificación del lenguaje Java para obtener más información en literales enteros.
— Ted Hopp

¿El literal que sigue? Entonces, por ejemplo, si tuviera 0x3fa. ¿El 3fa es la parte que se traduce a un número literal y 0x indica "este es un número hexadecimal"? @TedHopp?
— Llamado el

1
@KazRodgers - Exactamente. Tenga en cuenta que 0xo 0bpor sí mismo (sin ningún dígito a continuación) es una sintaxis ilegal en Java.
— Ted Hopp

1
@DmitryMinkovsky: el patrón de bits hexadecimales feen complemento a dos de 8 bits corresponde al valor decimal −2. Para conservar el valor, Integer.valueOf(byte)necesitaría producir ff ff ff fe(−2 en 32 bits, complemento a dos), no 00 00 00 fe(valor decimal 254). Esta transformación (de un bytevalor fea un intvalor ff ff ff fe) se conoce como extensión de signo y es parte de la especificación del lenguaje Java. El propósito de value & 0xffes deshacer la extensión del signo (es decir, simular la extensión cero, algo que Java no tiene).
— Ted Hopp

57

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

El literal hexadecimal 0xFF es un int (255) igual. Java representa int como 32 bits. Se ve así en binario:

00000000 00000000 00000000 11111111

Cuando lo hace un poco Y con este valor (255) en cualquier número, va a enmascarar (hacer CERO) todos menos los 8 bits más bajos del número (será como está).

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

& es algo así como% pero no realmente .

¿Y por qué 0xff? esto en ((potencia de 2) - 1). Todos ((potencia de 2) - 1) (por ejemplo, 7, 255 ...) se comportarán de forma similar al operador%.

Luego,
en binario, 0 es, todo ceros y 255 se ve así:

00000000 00000000 00000000 11111111

Y -1 se ve así

11111111 11111111 11111111 11111111

Cuando hace un AND bit a bit de 0xFF y cualquier valor de 0 a 255, el resultado es exactamente el mismo que el valor. Y si todavía hay algún valor superior a 255, el resultado estará entre 0-255.

Sin embargo, si lo hace:

-1 & 0xFF

usted obtiene

00000000 00000000 00000000 11111111, que NO es igual al valor original de -1 ( 11111111es 255 en decimal).


Pocas manipulaciones de bits más: (No relacionado con la pregunta)

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

Verifique que cualquier bit en particular esté establecido (1) o no (0) luego

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

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

Establecer (1) un bit en particular

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

Restablecer (0) un bit en particular

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

XOR

Solo tenga en cuenta que si realiza la operación XOR dos veces, obtendrá el mismo valor.

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

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

Una lógica más con XOR es

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

Lo anterior es útil para intercambiar dos variables sin temperatura como a continuación

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

O

a ^= b ^= a ^= b;

También eche un vistazo a @ Bit manipulation stackoverflow.com/questions/13422259/…
— Kanagavelu Sugumar


4

Ayuda a reducir muchos códigos. Ocasionalmente se utiliza en valores RGB que constan de 8 bits.

donde 0xff significa 24 (0's) y 8 (1's) como00000000 00000000 00000000 11111111

Enmascara efectivamente la variable, por lo que deja solo el valor en los últimos 8 bits e ignora el resto de los bits.

Se ve más en casos como cuando se intenta transformar valores de color de un formato especial a valores RGB estándar (que tiene una longitud de 8 bits).

Gran explicación ver aquí


0

En el sistema de formato de 32 bits, el valor hexadecimal 0xffrepresenta 00000000000000000000000011111111que está 255(15*16^1+15*16^0)en decimal. y el operador & bit a bit enmascara los mismos 8 bits más a la derecha que en el primer operando.


¿Puedes explicar un poco más?
— ashishdhiman2007
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.