Как анализировать негативный длинный шестнадцатеричный в 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 дополнения себя.)