¿Hay alguna manera de declarar un int sin firmar en Java?
O la pregunta también puede enmarcarse así: ¿Cuál es el equivalente Java de unsigned?
Solo para decirte el contexto en el que estaba mirando la implementación de Java String.hashcode()
. Quería probar la posibilidad de colisión si el entero fuera 32 unsigned int.
>>>
operador en lugar de>>
.Respuestas:
Java no tiene un tipo de datos para enteros sin signo .
Puede definir un en
long
lugar de unint
si necesita almacenar valores grandes.También puede usar un entero con signo como si no estuviera firmado. El beneficio de la representación del complemento a dos es que la mayoría de las operaciones (como suma, resta, multiplicación y desplazamiento a la izquierda) son idénticas a nivel binario para enteros con y sin signo. Sin embargo, algunas operaciones (división, desplazamiento a la derecha, comparación y fundición) son diferentes. A partir de Java SE 8, los nuevos métodos en la
Integer
clase le permiten utilizar completamente elint
tipo de datos para realizar operaciones aritméticas sin signo :Tenga en cuenta que las
int
variables todavía están firmadas cuando se declaran, pero ahora es posible utilizar la aritmética sin signo utilizando esos métodos en laInteger
clase.fuente
int
tipo de datos para representar un entero de 32 bits sin signo, que tiene un valor mínimo0
y un valor máximo de2^32-1
. - ver docs.oracle.com/javase/tutorial/java/nutsandbolts/… y docs.oracle.com/javase/8/docs/api/java/lang/Integer.htmlint
como si no estuviera firmado usando varios métodos.¡Hay una API para Entero sin signo y Largo en Java 8!
fuente
Integer
clase en Java 8 permite usar int sin signo, es la diferencia entre solo en el espacio y la velocidad (ya que en C / C ++ son primitivos, mientras que en Java, es un contenedor de objetos completo)int
s se desplazan , incluso si están firmados. Es C / C ++ donde se reinicia sin firmar, pero si se firma causa "Comportamiento indefinido" en el desbordamiento. Si "pasar" es su única preocupación, no necesita firmar. Supongo que es por eso que las rutinas CRC, etc. funcionan en Java sin esfuerzos adicionales. Y es por eso que la nueva API solo agrega análisis, formato, comparaciones, división y resto. Todas las demás operaciones, es decir, todas las manipulaciones de bits, pero también la suma, resta, multiplicación, etc., están haciendo lo correcto de todos modos.Si un valor en un int es con signo o sin signo depende de cómo se interpreten los bits: Java interpreta los bits como un valor con signo (no tiene primitivas sin signo).
Si tiene un int que desea interpretar como un valor sin signo (por ejemplo, si lee un int de un DataInputStream que sabe que contiene un valor sin signo), puede hacer el siguiente truco.
Tenga en cuenta que es importante que el literal hexadecimal sea un literal largo, no un literal int, de ahí la 'l' al final.
fuente
0xFFFFFF
y mantener el int?Necesitábamos números sin signo de modelar de MySQL sin signo
TINYINT
,SMALLINT
,INT
,BIGINT
en jOOQ , por lo que hemos creado Joou , una oferta biblioteca minimalista envoltorio tipos de números enteros sin signo en Java. Ejemplo:Todos estos tipos se extienden
java.lang.Number
y se pueden convertir en tipos primitivos y de orden superiorBigInteger
. Espero que esto ayude.(Descargo de responsabilidad: trabajo para la empresa detrás de estas bibliotecas)
fuente
Para números sin signo, puede usar estas clases de la biblioteca Guava :
Apoyan varias operaciones:
Lo que parece faltar en este momento son los operadores de cambio de bytes. Si los necesita, puede usar BigInteger de Java.
fuente
Úselo
char
para enteros sin signo de 16 bits.fuente
Quizás esto es lo que quisiste decir?
getUnsigned(0)
→ 0getUnsigned(1)
→ 1getUnsigned(Integer.MAX_VALUE)
→ 2147483647getUnsigned(Integer.MIN_VALUE)
→ 2147483648getUnsigned(Integer.MIN_VALUE + 1)
→ 2147483649fuente
2 * (long) Integer.MAX_VALUE + 2
es más fácil de entender que0x1_0000_0000L
? En ese sentido, ¿por qué no simplementereturn signed & 0xFFFF_FFFFL;
?Parece que puede manejar el problema de firma haciendo un "AND lógico" en los valores antes de usarlos:
Ejemplo (valor de
byte[]
header[0]
is0x86
):Resultado:
fuente
Aquí hay buenas respuestas, pero no veo ninguna demostración de operaciones bit a bit. Como dice Visser (la respuesta actualmente aceptada), Java firma enteros por defecto (Java 8 tiene enteros sin signo, pero nunca los he usado). Sin más preámbulos, hagámoslo ...
RFC 868 Ejemplo
¿Qué sucede si necesita escribir un entero sin signo en IO? Un ejemplo práctico es cuando desea generar el tiempo de acuerdo con RFC 868 . Esto requiere un número entero de 32 bits, big-endian, sin signo que codifique el número de segundos desde las 12:00 AM del 1 de enero de 1900. ¿Cómo codificaría esto?
Haga su propio entero de 32 bits sin signo como este:
Declarar una matriz de bytes de 4 bytes (32 bits)
Esto inicializa la matriz, consulte ¿Las matrices de bytes se inicializan a cero en Java? . Ahora tiene que llenar cada byte en la matriz con información en el orden big-endian (o little-endian si quiere causar estragos). Suponiendo que tiene un tiempo que contiene el tiempo (los enteros largos son de 64 bits en Java) llamado
secondsSince1900
(que solo utiliza los primeros 32 bits, y ha manejado el hecho de que Date hace referencia a las 12:00 AM del 1 de enero de 1970), luego puede usar el AND lógico para extraer bits de él y cambiar esos bits a posiciones (dígitos) que no se ignorarán cuando se conviertan en un Byte, y en orden big-endian.Nuestro
my32BitUnsignedInteger
ahora es equivalente a un entero big endian sin signo de 32 bits que se adhiere al estándar RCF 868. Sí, el tipo de datos largo está firmado, pero ignoramos ese hecho, porque asumimos que los segundosSince1900 solo usaron los 32 bits inferiores). Debido a convertir el largo en un byte, se ignorarán todos los bits superiores a 2 ^ 7 (primeros dos dígitos en hexadecimal).Fuente referenciada: Java Network Programming, cuarta edición.
fuente
Acabo de hacer este código, que convierte "this.altura" de negativo a positivo. Espero que esto ayude a alguien que lo necesita
fuente
Puede usar la función Math.abs (número). Devuelve un número positivo.
fuente
MIN_VALUE
0