Pergunta

Eu tenho algumas linhas de código dentro de um projeto, que eu não posso ver o valor de ...

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

Ele lê o filebuffer de um arquivo, armazenados como bytes, e depois transfere depois para buffer [i] como mostrado, mas eu não consigo entender o que o objectivo global é, todas as idéias?

Graças

Foi útil?

Solução

Como as outras respostas já foi dito, (currentByte & 0x7F) | (currentByte & 0x80) é equivalente a (currentByte & 0xFF). O JLS3 15.22.1 diz que esta é promovida a um int:

Quando ambos os operandos de um operador e, ^ Ou | são de um tipo que é convertível (§5.1.8) a uma primitiva tipo integral, numérico binário promoção é realizada pela primeira vez na operandos (§5.6.2). O tipo do expressão operador bit a bit é a Tipo promovido dos operandos.

5.6.2 diz que quando currentByte tem tipo byte e 0x7F é um int (e este é o caso), então ambos os operandos são promovidos a int.

Portanto, buffer será uma matriz de elemento tipo int ou mais larga.

Agora, através da realização de & 0xFF em um int, nós efetivamente mapear a gama byte originais -128..127 para a faixa sem assinatura 0..255, uma operação muitas vezes utilizados por java.io córregos por exemplo.

Você pode ver isso em ação no seguinte trecho de código. Note-se que para entender o que está acontecendo aqui, você tem que saber que armazena Java tipos integrais, exceto char, como complemento de 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));

Finalmente, para um exemplo do mundo real, confira o Javadoc e implementação do método read de 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;
}

Outras dicas

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

é equivalente a

 currentByte & (0x7F | 0x80)

o que equivale

 currentByte & 0xFF

que é exatamente o mesmo que

 currentByte

Edit:. Eu só olhei para o lado direito da atribuição, e eu ainda acho que o equivalance é verdade

No entanto, parece que o código quer lançar o byte assinado para um tipo maior ao interpretar o byte como sem assinatura.

Existe uma maneira mais fácil de elenco assinou-byte para unsigned em java?

Eu acho que alguém fez pensar muito aqui. Isso simplesmente não é certo.

Eu tenho mas uma observação

  • O autor original estava preocupado com o tempo de execução substituindo o byte com um inteiro assinado nativa (provavelmente 32-bit) e é explicitamente tentando nos dizer algo sobre o sinal mordeu ser "especial"?

É o código deixado para trás. A menos que você sabe que está em um tempo de execução de peixe? Qual é o tipo do 'buffer' de qualquer maneira?

A lógica bit a bit complicado é completamente supérfluo.

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

faz a mesma coisa. Se buffer é declarado como um array de bytes que você pode até mesmo deixar de fora o & 0xff, mas, infelizmente, a declaração não é mostrado.

A razão pode ser que o desenvolvedor original foi confundido por bytes a ser assinado em Java.

O resultado de uma operação AND tem um 1 em que os bits onde ambos os bits são 1, enquanto o resultado de uma operação OR hase um em que os bits onde qualquer um de bits Bot é 1.

Assim, um exemplo de avaliação para o valor 0x65:

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

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

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

A boa coisa sobre esses tipos de operações lógicas:. Você pode tentar todas as combinações possíveis (todos 256 deles) e verificar se você obter a resposta que você esperava

Acontece que, o arquivo que o byte foi sendo lidos estava em uma notação bit assinado, e de um comprimento diferente, pois foi requried para executar esta tarefa para permitir que ele seja estendido para o tipo int java, mantendo seu sinal correto:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top