Problema com bytes

5 respostas
I

Olá, sou novato com Java e estou tendo um problema com um código portado do C#:

return mTable[(mTable[this.i] + mTable[this.j]) % 256];

onde mTable é uma array de bytes (byte[])

O problema é que nessa linha, a soma de “mTable[this.i] + mTable[this.j]” dá um resultado negativo “-114”, e no C# não existe byte negativo, como conserto isso?

5 Respostas

RichardVaugh

Por acaso não está ocorrendo overflow na soma dos bytes ?
Pelo menos em Java uma atribuição de byte b = soma de dois bytes não é possível sem cast…

I

Se alguém puder dar uma analisada, aqui vai o código inteiro:
http://igorlira.pastebin.com/5nFPiGZS

O problema é no método MixTable(), linha 307

RichardVaugh

Na hora que é feito um cast na linha

  1. mTable[i] = (byte)kmTable[i];

Acontece que naquela matriz tem valores que não cabem em um byte no Java, o byte só suporte -128 até 127…
por isso o cast que você faz aí está eliminando alguns bits do valor resultante e o bit que fica no começo é 1, então o valor final fica negativo.

I

Então, como resolvo isso?

x111
RichardVaugh:
Na hora que é feito um cast na linha

292. mTable = (byte)kmTable[i];

Acontece que naquela matriz tem valores que não cabem em um byte no Java, o byte só suporte -128 até 127... por isso o cast que você faz aí está eliminando alguns bits do valor resultante e o bit que fica no começo é 1, então o valor final fica negativo.
Na verdade não está sendo "perdido" nenhum bit, o valor negativo está correto os bytes em java são representados em complemento de 2 ou seja 254 = -2 Para se obter o valor positivo pode se fazer uma operação and bit a bit. Exemplo:
byte byte01 = 127;
        byte byte02 = 127;
        byte resposta = (byte)(byte01 + byte02); //-2 = 254

        System.out.println(resposta);

        int valorSemSinal = resposta & 0xFF;
        System.out.println(valorSemSinal);
Para facilitar a explicação vou trabalhar como se um inteiro em java tivesse 16 bits ao invés de 32

o que acontecer é o seguinte:
-2 como byte possui 8 bits e equivale a 1111 1110 em binário. O byte mais significativo é 1 que indica que o valor é negativo
na operação bit a bit (resposta & 0xFF) o valor do byte é convertido implicitamente para inteiro e passa a equivaler em binário a 1111 1111 1111 1110 ou seja -2 em inteiro
0xFF equivale em binário a 0000 0000 1111 1111 e quando eu faço um and bit a bit com o valor da variável resposta eu zero [i]os dois bytes mais significativos
*
obtendo assim 0000 0000 1111 1110 que é 254 inteiro!!!!

agora olhe uma coisa -2 em um byte é igual a 1111 1110
agora veja o valor inteiro 000 000 1111 1110 os dois bytes menos significativos são idênticos**! O sinal é positivo por que o byte mais significativo está em 0

O mais importante disso é ver que o valor negativo do byte mantém a representação do seu valor, só que o bit mais significativo é interpretado como sinal!
Você só tem que tomar com cuidado com as operações pois se você for fazer 255 + 255, isso equivale a -1 + -1 que é -2 e não vai dar um overflow. Operações dentro dos limites são suportados tranquilamente.

Entendeu?

----------
Correção:
*Aonde se lê os dois bytes mais significativos, leia-se o byte mais significativo
**Aonde se lê os dois bytes menos significativos são idênticos leia-se os bits do byte menos significativo do valor inteiro é identico aos bits do byte -2

Criado 14 de janeiro de 2011
Ultima resposta 15 de jan. de 2011
Respostas 5
Participantes 3