Как анализировать негативный длинный шестнадцатеричный в Java

У нас есть приложение J2ME, которое должно читать шестнадцатеричные числа. Приложение уже слишком велико для некоторых телефонов, поэтому мы стараемся не включать какой-либо другой кодек или писать свою собственную функцию для этого.

Все числа являются 64-разрядными целыми знаками в шестнадцатеричном формате, когда мы используем Long.ParseLong(hex, 16), он корректно обрабатывает положительные числа, но генерирует исключение на отрицательных числах,

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

Как мы можем получить -1 из этой шестнадцатеричной строки, используя классы, предоставленные в самой Java?

Некоторые люди могут предположить, что мы должны написать наш hex как -1, как ожидалось Java. Извините, формат фиксирован протоколом, и мы не можем его изменить.

Ответ 1

Ваша проблема в том, что parseLong() не обрабатывает два дополнения - он ожидает, что знак будет присутствовать в форме '-.

Если вы разрабатываете профиль CDC, вы можете просто использовать

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

Но профиль CLDC не имеет этого класса. Там самый простой способ сделать то, что вам нужно, - это, вероятно, разделить длинный, разобрать его на две половины и перекомпилировать. Это работает:

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

UPDATE

С Java 8 вы можете использовать parseUnsignedLong():

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

Ответ 2

Разберите его в кусках.

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

Ответ 3

В худшем случае вы можете проверить, не содержит ли строка 16 символов, начинающихся с 8-F, и если это так, измените это на эквивалентный символ без самого значимого битового набора (т.е. вычитайте 8 из этого разряд), проанализировать результат и добавить обработанное значение к нижней границе подписанного долго? (По сути, просто делать 2 дополнения себя.)