tags:

views:

730

answers:

3

We have a J2ME application that needs to read hex numbers. The application is already too big for some phones so We try not to include any other codec or write our own function to do this.

All the numbers are 64-bit signed integers in hex, when we use Long.ParseLong(hex, 16), it handles positive numbers correctly but it throws exception on negative numbers,

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

How can we get -1 from that hex string using classes provided in Java itself?

Some people may suggest we should write our hex as -1 as Java expected. Sorry, the format is fixed by the protocol and we can't change it.

A: 

Worse case scenario, you could check to see if the string is 16 characters that begins with an 8-F, and if so, change that to the equivalent character w/o the most significant bit set (i.e. subtract 8 from that digit), parse the result, and add the parsed value to the lower bound of a signed long? (Essentially just doing the 2's complement yourself.)

Amber
Not quite. The first character could be from 8-F - those would all be negative.
Vinay Sajip
Two's complement negative numbers can also begin with E, D, C, B, A, 9, or 8
Avi
Yes, you're right. :)
Amber
+5  A: 

Your problem is that parseLong() does not handle two's complement - it expects the sign to be present in the form of a '-'.

If you're developing for the CDC profile, you can simple use

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

But the CLDC profile doesn't have that class. There, the easiest way to do what you need is probably to split up the long, parse it in two halves and recombine them. This works:

long msb = Long.parseLong("FFFFFFFF", 16);
long lsb = Long.parseLong("FFFFFFFF", 16);
long result = msb<<32 | lsb;
Michael Borgwardt
+3  A: 

Parse it in chunks.

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