Pregunta

Tengo unas pocas líneas de código dentro de un proyecto, que no puedo ver el valor de ...

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

Se lee el filebuffer de un archivo, se almacena como bytes, y luego se traslada entonces a la memoria intermedia [i] como se muestra, pero no puedo entender lo que el objetivo general es, alguna idea?

Gracias

¿Fue útil?

Solución

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

  

Cuando ambos operandos de un operador y,   ^ O | son de un tipo que es   convertible (§5.1.8) a una primitiva   tipo integral, numérico binario   promoción se realizó por primera vez en el   operandos (§5.6.2). El tipo de la   expresión operador de bits es la   Tipo promovido de los operandos.

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 de tipo de elemento int o más amplio.

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

Se puede ver esto en acción en el siguiente fragmento de código. Tenga en cuenta que para entender lo que está sucediendo aquí, usted tiene que saber que almacena Java tipos integrales, excepto char, como complemento a 2 valores.

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 read java.io.ByteArrayInputStream:

/**
 * 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;
}

Otros consejos

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

es equivalente a

 currentByte & (0x7F | 0x80)

que es igual a

 currentByte & 0xFF

que es exactamente lo mismo que

 currentByte

Edit: Yo sólo miraba el lado derecho de la asignación, y sigo pensando, la equivalencia es cierto

.

Sin embargo, parece que el código quiere emitir el byte con signo a un tipo más grande al interpretar el byte como no firmada.

¿Hay una manera más fácil de echar a bytes con signo sin firmar en Java?

Creo que alguien no pensar demasiado aquí. Eso no es correcto.

No tengo 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 para decirnos algo sobre el bit de signo de ser "especial"?

Es código dejado atrás. A menos que usted sabe que está en un tiempo de ejecución a pescado? ¿Qué es el tipo de 'amortiguador' de todos modos?

La lógica bit a bit complicado es totalmente 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 que puede incluso dejar de lado el y 0xff, pero por desgracia no se muestra la declaración.

La razón puede ser que el desarrollador original estaba confundido por bytes de ser firmado en Java.

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í que 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

Lo bueno de este tipo de operaciones lógicas:. Puede probar todas las combinaciones posibles (todos los 256 de ellos) y verificar que se obtiene la respuesta que esperaba

Resulta que el archivo de la cual el byte se están leyendo estaba en una notación bits con signo, y de una longitud diferente, por lo que se deberá añadir para realizar esta tarea para que pueda ser extendida a la java tipo int, conservando su signo correcto:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top