java - tipo - ¿La mejor manera de convertir un entero con signo a un largo sin firmar?
tipos de datos java (7)
¿Algo como esto?
int x = -1;
long y = x & 0x00000000ffffffffL;
¿O me estoy perdiendo algo?
public static long getUnsignedInt(int x) {
return x & 0x00000000ffffffffL;
}
Para ciertas funciones hash en Java sería bueno ver el valor como un entero sin signo (por ejemplo, para comparar con otras implementaciones) pero Java solo admite tipos firmados. Podemos convertir un int
firmado en un "unsigned" long
que:
public static final int BITS_PER_BYTE = 8;
public static long getUnsignedInt(int x) {
ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / BITS_PER_BYTE);
buf.putInt(Integer.SIZE / BITS_PER_BYTE, x);
return buf.getLong(0);
}
getUnsignedInt(-1); // => 4294967295
Sin embargo, esta solución parece una exageración por lo que realmente estamos haciendo. ¿Hay una manera más eficiente de lograr lo mismo?
La forma estándar en Java 8 es Integer.toUnsignedLong(someInt)
, que es equivalente a la respuesta de @ Mysticial .
Puedes usar una función como
public static long getUnsignedInt(int x) {
return x & (-1L >>> 32);
}
Sin embargo, en la mayoría de los casos no es necesario hacer esto. Puede utilizar soluciones alternativas en su lugar. p.ej
public static boolean unsignedEquals(int a, int b) {
return a == b;
}
Para más ejemplos de soluciones para el uso de valores sin signo. Clase de utilidad sin firmar
Solo mis 2 centavos aquí, pero creo que es una buena práctica usar:
public static long getUnsignedInt(int x) { return x & (~0L); // ~ has precedence over & so no real need for brackets }
en lugar de:
devuelve x & 0xFFFFFFFFL;
En esta situación no te preocupa cuántas F tiene la máscara. ¡Siempre funcionará!
otra solucion
public static long getUnsignedInt(int x) {
if(x > 0) return x;
long res = (long)(Math.pow(2, 32)) + x;
return res;
}
Guava proporciona UnsignedInts.toLong(int)
... así como una variedad de otras utilidades en enteros sin signo.
long abs(int num){
return num < 0 ? num * -1 : num;
}