¿Cuál es la mejor manera de evitar el hecho de que TODOS los bytes de Java están firmados?


En Java, no hay tal cosa como un byte sin signo.

Trabajando con algún código de bajo nivel, ocasionalmente necesita trabajar con bytes que tienen valores sin signo mayores que 128, lo que hace que Java los interprete como un número negativo debido al MSB que se usa para el signo.

¿Cuál es una buena manera de solucionar esto? (Decir no usar Java no es una opción)

Author: Max, 2008-08-14

7 answers

Al leer cualquier valor individual del array, cópielo en algo como un short o un int y convierta manualmente el número negativo en el valor positivo que debería ser.

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

Puede hacer una conversión similar al escribir en el array.

 19
Author: pauldoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-14 14:24:50

En realidad es posible deshacerse de la instrucción if y la adición si lo hace de esta manera.

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

De esta manera Java no interpreta el byte como un número negativo y voltea el bit de signo en el entero también.

 78
Author: ejack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-01 16:00:06

Usar ints es generalmente mejor que usar shorts porque java usa valores de 32 bits internamente de todos modos (Incluso para bytes, a menos que en una matriz), por lo que usar ints evitará la conversión innecesaria a/desde valores cortos en el bytecode.

 1
Author: izb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-19 08:03:27

Probablemente tu mejor apuesta es usar un entero en lugar de un byte. Tiene el espacio para permitir números mayores que 128 sin la sobrecarga de tener que crear un objeto especial para reemplazar byte.

Esto también es sugerido por personas más inteligentes que yo (todos)

 0
Author: stimms,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-14 14:22:24

La mejor manera de hacer la manipulación de bits/bytes sin signo es a través del uso de ints. A pesar de que están firmados tienen un montón de bits de repuesto (32 en total) para tratar como un byte sin signo. Además, todos los operadores matemáticos convertirán números de precisión fijos más pequeños a int. Ejemplo:

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

Debido a esto, lo mejor es simplemente quedarse con integer y enmascararlo para obtener los bits que le interesan. Ejemplo:

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

Aquí hay más información sobre Java primitive tipos http://mindprod.com/jgloss/primitive.html

Una última nota trivial, hay un número de precisión fija sin signo en Java. Ese es elchar primitivo.

 0
Author: martinatime,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-19 03:39:43

Sé que esta es una respuesta muy tardía, pero me encontré con este hilo cuando traté de hacer exactamente lo mismo. El problema es simplemente tratar de determinar si un byte Java es >127.

La solución simple es:

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

Si el problema real es >128, simplemente agregar otra condición a esa instrucción if hará el truco.

 0
Author: octo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-18 23:33:42

Supongo que podrías usar un corto para almacenarlos. No muy eficiente, pero realmente la única opción además de algún esfuerzo hercúleo que he visto.

 -1
Author: Nick Berardi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-14 14:17:48