En la página "Tipos de datos primitivos" de Oracle , se menciona que Java 8 agrega soporte para entradas y longs sin firmar:
int
: De forma predeterminada, elint
tipo de datos es un entero de complemento a dos con signo de 32 bits, que tiene un valor mínimo de −2 31 y un valor máximo de 2 31 −1. En Java SE 8 y versiones posteriores, puede utilizar elint
tipo de datos para representar un entero de 32 bits sin signo, que tiene un valor mínimo de 0 y un valor máximo de 2 32 −1. Use laInteger
clase para usarint
el tipo de datos como un entero sin signo. Consulte la sección Las clases de números para obtener más información. Se han agregado métodos estáticos comocompareUnsigned
,divideUnsigned
etc. a laInteger
clase para admitir las operaciones aritméticas para enteros sin signo.
long
: Ellong
tipo de datos es un entero de complemento a dos de 64 bits. El signolong
tiene un valor mínimo de −2 63 y un valor máximo de 2 63 −1. En Java SE 8 y posterior, puede utilizar ellong
tipo de datos para representar un 64 bits sin firmarlong
, que tiene un valor mínimo de 0 y un valor máximo de 2 64 −1. Utilice este tipo de datos cuando necesite un rango de valores más amplio que los proporcionados por int. LaLong
clase también contiene métodos comocompareUnsigned
,divideUnsigned
etc. para admitir operaciones aritméticas para unsignedlong
.
Sin embargo, no encuentro forma de declarar un número entero o largo sin firmar. El siguiente código, por ejemplo, da un mensaje de error del compilador de "el literal está fuera de rango" (estoy usando Java 8, por supuesto), cuando debería estar dentro del rango (el valor asignado es precisamente 2 64 -1) :
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
Entonces, ¿hay alguna forma de declarar un int o long sin firmar?
Respuestas:
Según la documentación que publicó y esta publicación de blog , no hay diferencia al declarar la primitiva entre un int / long sin firmar y uno firmado. El "nuevo soporte" es la adición de los métodos estáticos en las clases Integer y Long, por ejemplo, Integer.divideUnsigned . Si no está utilizando esos métodos, su "unsigned" por encima de 2 ^ 63-1 es simplemente un largo con un valor negativo.
De un vistazo rápido, no parece que haya una manera de declarar constantes enteras en el rango fuera de +/- 2 ^ 31-1, o +/- 2 ^ 63-1 para longs. Tendría que calcular manualmente el valor negativo correspondiente a su valor positivo fuera de rango.
fuente
Bueno, incluso en Java 8,
long
yint
todavía están firmados, solo algunos métodos los tratan como si no estuvieran firmados . Si desea escribir unlong
literal sin firmar de esa manera, puede hacerlostatic long values = Long.parseUnsignedLong("18446744073709551615"); public static void main(String[] args) { System.out.println(values); // -1 System.out.println(Long.toUnsignedString(values)); // 18446744073709551615 }
fuente
// Java 8 int vInt = Integer.parseUnsignedInt("4294967295"); System.out.println(vInt); // -1 String sInt = Integer.toUnsignedString(vInt); System.out.println(sInt); // 4294967295 long vLong = Long.parseUnsignedLong("18446744073709551615"); System.out.println(vLong); // -1 String sLong = Long.toUnsignedString(vLong); System.out.println(sLong); // 18446744073709551615 // Guava 18.0 int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString()); System.out.println(vIntGu); // -1 String sIntGu = UnsignedInts.toString(vIntGu); System.out.println(sIntGu); // 4294967295 long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615"); System.out.println(vLongGu); // -1 String sLongGu = UnsignedLongs.toString(vLongGu); System.out.println(sLongGu); // 18446744073709551615 /** Integer - Max range Signed: From −2,147,483,648 to 2,147,483,647, from −(2^31) to 2^31 – 1 Unsigned: From 0 to 4,294,967,295 which equals 2^32 − 1 Long - Max range Signed: From −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from −(2^63) to 2^63 − 1 Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1 */
fuente
No hay forma de declarar un unsigned long o int en Java 8 o Java 9. Pero algunos métodos los tratan como si estuvieran sin firmar, por ejemplo:
static long values = Long.parseUnsignedLong("123456789012345678");
pero esta no es una declaración de la variable.
fuente
Si el uso de una biblioteca de terceros es una opción, existe jOOU (una biblioteca derivada de jOOQ ), que ofrece tipos de envoltura para números enteros sin signo en Java. Eso no es exactamente lo mismo que tener soporte de tipo primitivo (y por lo tanto código de bytes) para tipos sin firmar, pero quizás aún sea lo suficientemente bueno para su caso de uso.
import static org.joou.Unsigned.*; // and then... UByte b = ubyte(1); UShort s = ushort(1); UInteger i = uint(1); ULong l = ulong(1);
Todos estos tipos se extienden
java.lang.Number
y pueden convertirse en tipos primitivos de orden superior yBigInteger
.(Descargo de responsabilidad: trabajo para la empresa detrás de estas bibliotecas)
fuente