2009-02-18 16 views
10

tengo unas pocas líneas de código dentro de un proyecto, que no puedo ver el valor de ...AND bit a bit, bit a bit pregunta Incluido O, en Java

buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80); 

Se lee el filebuffer de una archivo, almacenado como bytes, y luego se transfiere al búfer [i] como se muestra, pero no puedo entender cuál es el propósito general, ¿alguna idea?

Gracias

Respuesta

9

Como las otras respuestas ya se ha dicho, es equivalente a (currentByte & 0x7F) | (currentByte & 0x80)(currentByte & 0xFF).El JLS3 15.22.1 dice que esto es promovido a un int:

Cuando ambos operandos de un operador &, ^ o | son de un tipo que es convertible (§5.1.8) a un tipo integral primitivo , la promoción numérica binaria se realiza primero en los operandos (§5.6.2). El tipo de expresión de operador bit a bit es el tipo promocionado de los operandos.

porque JLS3 5.6.2 dice que cuando currentByte tiene tipo byte y 0x7F es un int (y este es el caso), entonces los dos operandos son promovidos a int.

Por lo tanto, buffer será una matriz del elemento tipo int o más.

Ahora, mediante la realización de & 0xFF en una int, que efectivamente en el mapa los byte gama original -128..127 en el rango 0..255 sin firmar, una operación a menudo utilizado por java.io corrientes, por ejemplo.

Puede ver esto en acción en el siguiente fragmento de código. Tenga en cuenta que para comprender lo que está sucediendo aquí, debe saber que Java almacena tipos integrales, excepto char, como valores 2's complement.

byte b = -123; 
int r = b; 
System.out.println(r + "= " + Integer.toBinaryString(r)); 
int r2 = b & 0xFF; 
System.out.println(r2 + "= " + Integer.toBinaryString(r2)); 

Por último, para un ejemplo del mundo real, echa un vistazo a la Javadoc y la aplicación del método de java.io.ByteArrayInputStreamread:

/** 
* Reads the next byte of data from this input stream. The value 
* byte is returned as an <code>int</code> in the range 
* <code>0</code> to <code>255</code>. If no byte is available 
* because the end of the stream has been reached, the value 
* <code>-1</code> is returned. 
*/ 
public synchronized int read() { 
return (pos < count) ? (buf[pos++] & 0xff) : -1; 
} 
3

Creo que alguien pensó demasiado aquí. Eso no está bien.

no tener más que una observación

  • El autor original estaba preocupado por el tiempo de ejecución reemplazando el byte con un entero con signo nativa (presumiblemente de 32 bits) y está tratando de forma explícita decirnos algo acerca de la señal poco siendo "especial"?

Es código dejado atrás. ¿A menos que sepas que estás en un tiempo de fuga apestoso? ¿Cuál es el tipo de 'buffer' de todos modos?

+0

¡LOL, esto es con lo que tengo que trabajar! :) – Dave

+0

Ambos son matrices os bytes Probé la sugerencia de Timbo, y se fubared cuando se cambió: -/ – Dave

+0

el búfer es del tipo de elemento int o más ancho, de lo contrario no debería compilarse. – eljenso

2

La complicada lógica bit a bit es completamente superflua.

for (int i = 0; i < buffer.length; i++) { 
    buffer[i] = filebuffer[currentPosition + i] & 0xff; 
} 

hace lo mismo. Si el buffer se declara como una matriz de bytes, puede omitir el & 0xff, pero desafortunadamente la declaración no se muestra.

La razón puede ser que el desarrollador original fue confundido por los bytes que se firman en Java.

+0

El búfer nunca puede ser de tipo byte [] con & 0xFF. Sin él, puede cambiar el resultado. – eljenso

+0

Tiene razón, eso necesitaría un elenco. – starblue

4
(currentByte & 0x7F) | (currentByte & 0x80) 

es equivalente a

currentByte & (0x7F | 0x80) 

lo que equivale a

currentByte & 0xFF 

que es exactamente lo mismo que

currentByte 

Editar: Yo sólo miraba el lado derecho de la asignación, y todavía creo que la e la quivalencia es verdadera

Sin embargo, parece que el código desea convertir el byte con signo a un tipo más grande al interpretar el byte como unsigned.

¿Hay alguna forma más fácil de convertir byte con signo a unsigned en java?

+0

El último paso es incorrecto, porque los bytes negativos se extenderán a números enteros negativos, mientras que currentByte y 0xFF son positivos. – starblue

+0

No hay nada en el código que implique que el búfer sea una matriz de tipo más ancho que el byte. – Welbog

+0

Está realmente mal, y no funciona – Dave

2

El resultado de un AND bit a bit operación tiene un 1 en la que los bits donde ambos bits son 1, mientras que el resultado de una operación OR operación hase una en que los bits donde o bien uno de los bits bot es 1.

Así una evaluación ejemplo para el valor 0x65:

01100101 0x65 
& 01111111 0x7F 
=============== 
    01100101 0x65 

    01100101 0x65 
& 10000000 0x80 
=============== 
    00000000 0x00 

    01100101 0x65 
| 00000000 0x00 
=============== 
    01100101 0x65 
+0

Su | el paso en la parte inferior está mal. El resultado de x | 0 para todo x es x. – Welbog

+0

obtengo 01100101 0x65 debajo de la línea (la última operación es |, no &) – tehvan

+0

Gracias, por supuesto su derecho. Creo que necesito más café – Gumbo

0

Lo bueno de este tipo de operaciones lógicas: se puede probar cada combinación posible (todos los 256) y verificar que obtenga la respuesta que esperaba.

0

Resulta que el archivo desde el que se leía el byte estaba en una notación de bit con signo, y de una longitud diferente, por lo tanto, se requirió realizar esta tarea para permitir que se extendiera al tipo java int, mientras conservando su signo correcto :)