Declarar un int sin firmar en Java

Resuelto Harshdeep asked hace 12 años • 10 respuestas

¿Hay alguna manera de declarar un int sin firmar en Java?

O la pregunta también podría plantearse de la siguiente manera: ¿Cuál es el equivalente en Java de unsigned?

Solo para decirles el contexto en el que estaba mirando la implementación de Java String.hashcode(). Quería probar la posibilidad de colisión si el número entero fuera 32 int sin signo.

Harshdeep avatar Mar 25 '12 01:03 Harshdeep
Aceptado

Java no tiene un tipo de datos para enteros sin signo .

Puede definir a longen lugar de an intsi necesita almacenar valores grandes.

También puede utilizar un número entero con signo como si no tuviera signo. El beneficio de la representación en 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 de la Integerclase le permiten utilizar completamente el inttipo de datos para realizar aritmética sin signo :

En Java SE 8 y versiones posteriores, puede utilizar el tipo de datos int 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. Utilice la clase Integer para utilizar el tipo de datos int como un entero sin signo. Se han agregado métodos estáticos como compareUnsigned, etc. a la clase Integer para admitir operaciones aritméticas para enteros sin signo.divideUnsigned

Tenga en cuenta que intlas variables todavía están firmadas cuando se declaran, pero ahora es posible realizar aritmética sin firmar utilizando esos métodos en la Integerclase.

Simeon Visser avatar Mar 24 '2012 18:03 Simeon Visser

Si un valor en un int está firmado o sin firmar depende de cómo se interpretan 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, lee un int de un DataInputStreamque sabe que debe interpretarse como un valor sin signo), puede hacer el siguiente truco.

int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffL;

Nota: es importante que el literal hexadecimal sea un longliteral, no un intliteral, de ahí la 'L' al final.

Zsolt Safrany avatar Apr 08 '2014 13:04 Zsolt Safrany

Necesitábamos números sin signo para modelar el TINYINT, SMALLINT, INT, sin signo de MySQL BIGINTen jOOQ , razón por la cual hemos creado jOOU , una biblioteca minimalista que ofrece tipos contenedores para números enteros sin signo en Java. Ejemplo:

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.Numbery se pueden convertir en tipos primitivos de orden superior y BigInteger. Espero que esto ayude.

(Descargo de responsabilidad: trabajo para la empresa detrás de estas bibliotecas)

Lukas Eder avatar Aug 06 '2014 11:08 Lukas Eder

Para números sin signo, puede utilizar estas clases de la biblioteca Guava :

  • Entero sin signo
  • Sin firmarLargo

Soportan diversas operaciones:

  • más
  • menos
  • veces
  • modificación
  • dividido por

Lo que parece faltar en este momento son los operadores de desplazamiento de bytes. Si los necesita, puede utilizar BigInteger de Java.

Andrejs avatar Aug 06 '2014 11:08 Andrejs

¿Quizás esto es lo que quisiste decir?

long getUnsigned(int signed) {
    return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
  • getUnsigned(0)→ 0
  • getUnsigned(1)→ 1
  • getUnsigned(Integer.MAX_VALUE)→ 2147483647
  • getUnsigned(Integer.MIN_VALUE)→ 2147483648
  • getUnsigned(Integer.MIN_VALUE + 1)→ 2147483649
Matthias Ronge avatar Jan 12 '2016 12:01 Matthias Ronge