2009-09-11 9 views
11

Tenemos una aplicación J2ME que necesita leer números hexadecimales. La aplicación ya es demasiado grande para algunos teléfonos, así que tratamos de no incluir ningún otro códec o escribir nuestra propia función para hacer esto.Cómo analizar Negative Long in Hex en Java

Todos los números son enteros con signo de 64 bits en hexadecimal, cuando usamos Long.ParseLong (hex, 16), se maneja correctamente los números positivos, pero ha producido una excepción en números negativos,

long l = Long.parseLong("FFFFFFFFFFFFFFFF", 16); 

¿Cómo puede obtenemos -1 de esa cadena hexadecimal usando las clases provistas en Java?

Algunas personas pueden sugerir que deberíamos escribir nuestro hex como -1 como esperaba Java. Lo sentimos, el protocolo lo arregla y no podemos cambiarlo.

Respuesta

20

Su problema es que parseLong() no maneja el complemento a dos: espera que el signo esté presente en forma de '-'.

Si está desarrollando para el perfil de CDC, puede utilizar sencilla

long l = new BigInteger("FFFFFFFFFFFFFFFF", 16).longValue() 

Pero el perfil CLDC no tiene esa clase. Allí, la forma más fácil de hacer lo que necesita es, probablemente, dividir el largo, analizarlo en dos mitades y recombinarlas. Esto funciona:

long msb = Long.parseLong("FFFFFFFF", 16); 
long lsb = Long.parseLong("FFFFFFFF", 16); 
long result = msb<<32 | lsb; 

ACTUALIZACIÓN

A partir de Java 8, puede utilizar parseUnsignedLong():

long l = Long.parseUnsignedLong("FFFFFFFFFFFFFFFF", 16); 
0

Peor escenario, puede comprobar si la cadena tiene 16 caracteres que comienza con un 8-F, y si es así, cámbielo al carácter equivalente sin el bit más significativo (es decir, reste 8 de ese dígito), analiza el resultado y agrega el valor analizado al límite inferior de un largo firmado (Esencialmente solo hacer el complemento a 2 usted mismo.)

+1

No del todo. El primer personaje podría ser de 8-F: todos serían negativos. –

+1

Los números negativos del complemento de dos también pueden comenzar con E, D, C, B, A, 9 o 8 – Avi

+0

Sí, tiene razón. :) – Amber

7

analizarlo en trozos.

long l = (Long.parseLong("FFFFFFFFF",16)<<32) | Long.parseLong("FFFFFFFF",16);