Necesito convertir un número en un byte sin firmar. El número siempre es menor o igual a 255, por lo que cabe en un byte.
También necesito convertir ese byte nuevamente en ese número. ¿Cómo haría eso en Java? He intentado varias formas y ninguna funciona. Esto es lo que estoy tratando de hacer ahora:
int size = 5;
// Convert size int to binary
String sizeStr = Integer.toString(size);
byte binaryByte = Byte.valueOf(sizeStr);
y ahora para convertir ese byte nuevamente en el número:
Byte test = new Byte(binaryByte);
int msgSize = test.intValue();
Claramente, esto no funciona. Por alguna razón, siempre convierte el número en 65
. ¿Alguna sugerencia?
Respuestas:
Un byte siempre está firmado en Java. Sin embargo, puede obtener su valor sin firmar haciendo un and binario con 0xFF:
fuente
0xFF
dan como resultado un entero sin signo? Alguna explicación sería realmente útil.Java 8 permite
Byte.toUnsignedInt
convertirbyte
aint
por conversión sin firmar. En el JDK de Oracle, esto simplemente se implementareturn ((int) x) & 0xff;
porque HotSpot ya comprende cómo optimizar este patrón, pero podría estar intrinsificado en otras VM. Más importante aún, no se necesitan conocimientos previos para comprender lo que hace una llamada atoUnsignedInt(foo)
.En total, Java 8 proporciona métodos para convertir
byte
yshort
a unsignedint
ylong
, yint
a unsignedlong
. Un método para convertirbyte
a firmarshort
se omitió deliberadamente porque la JVM sólo proporciona aritmética sobreint
ylong
de todos modos.Para convertir un int volver a un byte, sólo tiene que utilizar un yeso:
(byte)someInt
. La conversión primitiva de estrechamiento resultante descartará todos menos los últimos 8 bits.fuente
Si solo necesita convertir un valor esperado de 8 bits de un int con signo a un valor sin firmar, puede usar el desplazamiento de bits simple:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
Si utiliza algo diferente al
int
tipo base, obviamente deberá ajustar la cantidad de cambio: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.htmlAdemás, tenga en cuenta que no puede usar el
byte
tipo, si lo hace, dará como resultado un valor firmado como lo mencionaron otros respondedores. El tipo primitivo más pequeño que podría usar para representar un valor sin signo de 8 bits sería ashort
.fuente
La
Integer.toString(size)
llamada se convierte en la representación char de su entero, es decir, el char'5'
. La representación ASCII de ese carácter es el valor 65.Primero debe analizar la cadena a un valor entero, por ejemplo, usando
Integer.parseInt
, , para recuperar el valor int original.Como conclusión, para una conversión firmada / sin firmar, es mejor dejar
String
fuera de la imagen y usar la manipulación de bits como sugiere @JB.fuente
String sizeStr = Integer.toString(size); int sizeInt = Integer.parseInt(sizeStr); byte binaryByte = Byte.valueOf((byte) sizeInt);
String.getBytes()
produce los valores ASCII de los caracteres contenidos en el texto, no los valores numéricos de los dígitos. Es necesario para analizar la cadena en un valor numérico, como he indicado anteriormente.La solución funciona bien (¡gracias!), Pero si desea evitar la transmisión y dejar el trabajo de bajo nivel al JDK, puede usar un DataOutputStream para escribir sus int y un DataInputStream para volver a leerlos. Se tratan automáticamente como sin firmar bytes entonces:
Para convertir int's en bytes binarios;
Leyendo de nuevo en:
Esp. útil para manejar formatos de datos binarios (por ejemplo, formatos de mensajes planos, etc.)
fuente
Excepto
char
, todos los demás tipos de datos numéricos en Java están firmados.Como se dijo en una respuesta anterior, puede obtener el valor sin firmar realizando una
and
operación con0xFF
. En esta respuesta, voy a explicar cómo sucede.Si su máquina es de 32 bits, entonces el
int
tipo de datos necesita 32 bits para almacenar valores.byte
solo necesita 8 bits.La
int
variablei
se representa en la memoria de la siguiente manera (como un entero de 32 bits).Entonces la
byte
variableb
se representa como:Como
byte
s no están firmados, este valor representa-22
. (Busque el complemento de 2 para aprender más sobre cómo representar números enteros negativos en la memoria)Entonces, si lanzas es
int
, seguirá siendo-22
porque el lanzamiento conserva el signo de un número.El
32-bit
valor de conversión deb
realizar laand
operación con0xFF
.Entonces obtienes
234
la respuesta.fuente
Manejo de bytes y enteros sin signo con BigInteger:
fuente
Aunque es demasiado tarde, me gustaría dar mi opinión sobre esto, ya que podría aclarar por qué funciona la solución proporcionada por JB Nizet. Me encontré con este pequeño problema trabajando en un analizador de bytes y en la conversión de cadenas yo mismo. Cuando copia de un tipo integral de mayor tamaño a un tipo integral de menor tamaño, ya que este documento de Java dice que esto sucede:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3 Una conversión de restricción de un entero con signo a un tipo integral T simplemente descarta todo menos el n más bajo bits de orden, donde n es el número de bits utilizados para representar el tipo T.Además de una posible pérdida de información sobre la magnitud del valor numérico, esto puede provocar que el signo del valor resultante difiera del signo del valor de entrada .
Puede estar seguro de que un byte es un tipo integral, ya que este documento de Java dice https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html byte: el tipo de datos de byte es un dos de 8 bits firmado complemento entero.
Entonces, en el caso de convertir un número entero (32 bits) en un byte (8 bits), simplemente copie los últimos (8 bits menos significativos) de ese número entero en la variable de byte dada.
La segunda parte de la historia involucra cómo los operadores unarios y binarios de Java promueven los operandos. https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 La conversión primitiva de ampliación (§5.1.2) se aplica para convertir uno o ambos operandos como se especifica por las siguientes reglas:
Si alguno de los operandos es de tipo double, el otro se convierte en double.
De lo contrario, si alguno de los operandos es de tipo flotante, el otro se convierte en flotante.
De lo contrario, si alguno de los operandos es de tipo long, el otro se convierte en long.
De lo contrario, ambos operandos se convierten al tipo int.
Tenga la seguridad de que si está trabajando con el tipo integral int y / o inferior, se promoverá a un int.
También me rasqué la cabeza con esto :). Hay una buena respuesta para esto aquí por rgettman. ¿Operadores bit a bit en java solo para enteros y largos?
fuente
Si desea utilizar las clases contenedoras primitivas, esto funcionará, pero todos los tipos de Java están firmados de forma predeterminada.
fuente
en java 7
resultado: 254
fuente