Qual é a melhor forma de contornar o fato de que TODOS os bytes Java são assinados?

StackOverflow https://stackoverflow.com/questions/11088

  •  08-06-2019
  •  | 
  •  

Pergunta

Em Java, não há tal coisa como um unsigned byte.

Trabalhando com algumas código de baixo nível, ocasionalmente, você precisa trabalhar com bytes que não assinados valores maiores do que 128, o que faz com que o Java para interpretá-las como um número negativo, devido ao MSB sendo usado para assinar.

O que é uma boa maneira de contornar isso?(Dizendo que não usam o Java não é uma opção)

Foi útil?

Solução

Quando a leitura de qualquer valor único a partir da matriz de cópia em algo como um curto-circuito ou um int e converter manualmente o número negativo para o positivo, valor que deve ser.

byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value

Você pode fazer uma conversão semelhante ao escrever para a matriz.

Outras dicas

Na verdade, é possível livrar-se da instrução se e a adição, se você fizer assim.

byte[] foobar = ..;
int value = (foobar[10] & 0xff);

Desta forma, o Java não interpretar o byte como um número negativo e inverter o bit de sinal na inteiro também.

Usando ints é geralmente melhor do que usar shorts porque o java utiliza valores de 32 bits internamente de qualquer maneira (Mesmo para bytes, a menos que em uma matriz) assim, usando ints evitará a conversão de/para curto valores em bytecode.

Provavelmente a sua melhor aposta é a utilização de um número inteiro em vez de um byte.Ele tem o espaço para permitir números maiores do que 128 sem a sobrecarga de ter que criar um objeto especial, para substituir o byte.

Isso também é sugerido por gente mais inteligente do que eu (todos)

A melhor maneira de fazer a manipulação de bits/bytes não assinados é através do uso de ints.Mesmo que eles são assinados têm a abundância de reposição bits (32 no total) para tratar como um unsigned byte.Além disso, todos os operadores matemáticos irá converter menores fixo de números de precisão int.Exemplo:

short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short

Por isso é melhor ficar com número inteiro e uma máscara, para obter os bits que você está interessado.Exemplo:

int a = 32;
int b = 128;
int foo = (a + b) | 255;

Aqui está mais algumas informações sobre tipos primitivos de Java http://mindprod.com/jgloss/primitive.html

Uma última observação trivial, há um unsigned fixa número de precisão em Java.Que é o char primitivo.

Eu sei que isto é muito tarde, resposta, mas me deparei com esta discussão ao tentar fazer exatamente a mesma coisa.O problema é simplesmente a tentar determinar se um byte Java é >127.

A solução é simples:

if((val & (byte)0x80) != 0) { ... }

Se o real problema é >128 em vez disso, apenas adicionando uma outra condição para que a instrução se irá fazer o truque.

Eu acho que você poderia usar apenas um curto período de armazená-los.Não muito eficiente, mas realmente a única opção além de algumas esforço sobre-humano que eu já vi.

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