Как выполнить преобразование неподписанного в подписанное в Java? - PullRequest
5 голосов
/ 14 октября 2010

Скажите, что я прочитал эти байты: "6F D4 06 40" с устройства ввода.Число представляет собой долготу в формате MilliArcSeconds.Верхний бит (0x80000000) в основном всегда равен нулю и игнорируется для этого вопроса.

Я могу легко преобразовать байты в целое число без знака : 1876166208

Но как мне преобразовать это значение без знака в его окончательную форму 31-разрядного целого числа со знаком?

Пока все, что я придумал, это:

  1. , если значение & 0x40000000, то оно на самом деле отрицательное, нужно преобразовать его
  2. Если оно отрицательное, убратьстарший бит и сделать что-то с оставшимися битами ...

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

Другой способ задать вопрос: как преобразовать целое число без знака в 31-разрядное целое число со знаком в Java?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 14 октября 2010

Ответ зависит от того, что должны представлять младшие 31 бит вашего входа.

int input = 0x6FD40640 & 0x7FFFFFFF; //strip top bit; only here for clarity

Вход без знака: 0x6FD40640 == 1876166208

Дополнение к двум (желаемый результат: -271317440)

A дополнение до двух integer - это единица, в которой -1 имеет все установленные биты, и отсюда уменьшается число отрицательных отрицательных чисел. Первый бит по-прежнему действует как знаковый бит.

1000 -> -8
1001 -> -7
...
1110 -> -2
1111 -> -1
0000 ->  0
0001 ->  1

Если младшие 31 бит представляют собой целое число с дополнением до двух, то я думаю, что вы должны просто сделать это:

input = (input << 1) >> 1;

Это связано с тем, что Java хранит целые числа внутри двоичного дополнения: все, что мы делаем, это смещаемся влево, а затем смещаемся назад вправо (со знаком), так что знаковый бит берется и целое число изменяется с 31 до 32 бит.

Дополнение (желаемый вывод: -802424384)

A числовое представление - это то, где первый бит является выделенным знаковым битом, а остальные биты представляют величину. Младшие биты -100 будут такими же, как младшие биты 100:

 1111 -> -7
 1110 -> -6
 ...
 1001 -> -1
 1000 -> -0 (anomoly)
 0000 ->  0
 0001 ->  1

Если младшие 31 бит представляют собой целое число , равное *1026* (т. Е. Знаковый бит, за которым следуют 30 битов, представляющих величину без знака), то вам необходимо преобразовать его в дополнение к двум, чтобы Java извлекла ценить правильно. Для этого нужно просто извлечь младшие 30 бит и умножить на -1:

if ( input & 0x40000000 ) {
   input = (input & 0x3FFFFFFF) * -1;
}

Вы сказали в комментариях вопроса, что после преобразования в градусы (деления на 3600000) вы получите около -75,36. Когда я делю -271317440 на 3600000, я получаю -75.36595555555556 , так что я предполагаю, что ваш входной формат дополняет два, поэтому мой первый и оригинальный ответ был правильным.

0 голосов
/ 15 октября 2010

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

// Convert the hex bytes to an unsigned integer
long MAS = Integer.ValueOf("6F D4 06 40".replace (" ",""),16);
boolean isLongitudeNegative = false;

// Is the negative-bit set? If so, strip it and toggle all bits.
if (MAS & 0x40000000 > 0) {
    // then it's negative, so strip the negative bit and flip all the other bits
    MAS ^= 0xFFFFFFFF;
    // Throw away the unused bit.
    MAS &= 0x7FFFFFFF;
    isLongitudeNegative = true;
}

// Now convert from MAS to degrees minutes seconds
String DMS = convertMASToDMS(isLongitudeNegative,MAS);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...