Каков наилучший способ обойти тот факт, что все байты Java подписаны? - PullRequest
57 голосов
/ 14 августа 2008

В Java нет такой вещи как неподписанный байт.

Работая с некоторым кодом низкого уровня, иногда вам нужно работать с байтами, у которых значения без знака больше 128, что заставляет Java интерпретировать их как отрицательное число из-за MSB, используемого для знака.

Какой хороший способ обойти это? (Сказать не использовать Java не вариант)

Ответы [ 7 ]

78 голосов
/ 21 августа 2008

На самом деле можно избавиться от оператора if и дополнения, если вы сделаете это следующим образом.

byte[] foobar = ..;
int value = (foobar[10] & 0xff);

Таким образом, Java не интерпретирует байт как отрицательное число и также переворачивает бит знака на целое число.

19 голосов
/ 14 августа 2008

При чтении любого отдельного значения из массива скопируйте его в что-то вроде short или целого числа и вручную конвертируйте отрицательное число в положительное значение, которое должно быть.

byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value

Вы можете сделать аналогичное преобразование при записи в массив.

1 голос
/ 19 августа 2008

Использование ints обычно лучше, чем использование шорт, потому что в любом случае java использует 32-битные значения внутри себя (даже для байтов, если не в массиве), поэтому использование ints позволит избежать ненужного преобразования в / из коротких значений в байт-коде.

0 голосов
/ 19 февраля 2011

Я знаю, что это очень поздний ответ, но я наткнулся на эту тему, когда пытался сделать то же самое. Проблема заключается в попытке определить, является ли байт Java> 127.

Простое решение:

if((val & (byte)0x80) != 0) { ... }

Если реальная проблема составляет> 128, просто добавьте еще одно условие к этому оператору if.

0 голосов
/ 19 августа 2008

Лучший способ сделать битовые манипуляции / неподписанные байты - использовать int s. Несмотря на то, что они подписаны, у них есть много свободных битов (всего 32), которые можно рассматривать как неподписанный байт. Кроме того, все математические операторы преобразуют меньшие числа с фиксированной точностью в int . Пример:

short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short

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

int a = 32;
int b = 128;
int foo = (a + b) | 255;

Вот еще немного информации о примитивных типах Java http://mindprod.com/jgloss/primitive.html

Последнее тривиальное примечание: в Java есть одно число без знака с фиксированной точностью. Это char примитив.

0 голосов
/ 14 августа 2008

Вероятно, вам лучше всего использовать целое число, а не байт. В нем есть место для чисел, превышающих 128, без необходимости создавать специальный объект для замены байта.

Это также предлагают люди умнее меня (всех)

0 голосов
/ 14 августа 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...