2 дополнить шестнадцатеричное число до десятичного числа в Java - PullRequest
12 голосов
/ 15 июля 2011

У меня есть шестнадцатеричная строка, которая представляет номер дополнения 2. Есть ли простой способ (библиотеки / функции) для перевода шестнадцатеричного числа в десятичное, не работая напрямую с его битами ??

например. Это ожидаемый результат с учетом гексагона слева:

"0000" => 0
"7FFF" => 32767 (max positive number)
"8000" => -32768 (max negative number)
"FFFF" => -1

Спасибо!

Ответы [ 3 ]

19 голосов
/ 15 июля 2011

Кажется, что это обманывает Java в преобразовании числа без форсирования положительного результата:

Integer.valueOf("FFFF",16).shortValue(); // evaluates to -1 (short)

Конечно, это работает только для дополнений в 8, 16, 32 и 64-битных 2:

Short.valueOf("FF",16).byteValue(); // -1 (byte)
Integer.valueOf("FFFF",16).shortValue(); // -1 (short)
Long.valueOf("FFFFFFFF",16).intValue(); // -1 (int)
new BigInteger("FFFFFFFFFFFFFFFF",16).longValue(); // -1 (long)

Пример здесь .

8 голосов
/ 15 июля 2011

Просто напишите служебный метод:

 public static Integer twosComp(String str) throws java.lang.Exception {
       Integer num = Integer.valueOf(str, 16);
       return (num > 32767) ? num - 65536 : num;
 }

Тесты:

 twosComp("7FFF") -> 32767
 twosComp("8000") -> -32768
 twosComp("FFFF") -> -1
3 голосов
/ 15 июля 2011

Это, кажется, работает достаточно хорошо. Его можно обмануть, передав ему строки нестандартной длины: «FFF» отображается в -1. Нулевое заполнение исправит ошибку.

Вам не ясно, какой тип возврата вы хотите, поэтому я возвратил Number в любом подходящем размере.

public Number hexToDec(String hex)  {
   if (hex == null) {
      throw new NullPointerException("hexToDec: hex String is null.");
   }

   // You may want to do something different with the empty string.
   if (hex.equals("")) { return Byte.valueOf("0"); }

   // If you want to pad "FFF" to "0FFF" do it here.

   hex = hex.toUpperCase();

   // Check if high bit is set.
   boolean isNegative =
      hex.startsWith("8") || hex.startsWith("9") ||
      hex.startsWith("A") || hex.startsWith("B") ||
      hex.startsWith("C") || hex.startsWith("D") ||
      hex.startsWith("E") || hex.startsWith("F");

   BigInteger temp;

   if (isNegative) {
      // Negative number
      temp = new BigInteger(hex, 16);
      BigInteger subtrahend = BigInteger.ONE.shiftLeft(hex.length() * 4);
      temp = temp.subtract(subtrahend);
   } else {
      // Positive number
      temp = new BigInteger(hex, 16);
   }

   // Cut BigInteger down to size.
   if (hex.length() <= 2) { return (Byte)temp.byteValue(); }
   if (hex.length() <= 4) { return (Short)temp.shortValue(); }
   if (hex.length() <= 8) { return (Integer)temp.intValue(); }
   if (hex.length() <= 16) { return (Long)temp.longValue(); }
   return temp;
}

Пример вывода:

"33" -> 51
"FB" -> -5
"3333" -> 13107
"FFFC" -> -4
"33333333" -> 53687091
"FFFFFFFD" -> -3
"3333333333333333" -> 3689348814741910323
"FFFFFFFFFFFFFFFE" -> -2
"33333333333333333333" -> 241785163922925834941235
"FFFFFFFFFFFFFFFFFFFF" -> -1
...