Каков наилучший способ обойти тот факт, что все байты Java Java подписаны?
В Java нет такой вещи, как unsigned byte.
Работа с некоторым кодом низкого уровня, иногда вам нужно работать с байтами с неподписанными значениями больше 128, что заставляет Java интерпретировать их как отрицательное число из-за того, что MSB используется для знака.
Какой хороший способ обойти это? (Говорить не использовать Java не вариант)
Ответы
Ответ 1
При чтении любого отдельного значения из массива скопируйте его в нечто вроде короткого или int и вручную преобразуйте отрицательное число в положительное значение, которое оно должно быть.
byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value
Вы можете сделать подобное преобразование при записи в массив.
Ответ 2
@pauldoo
На самом деле можно избавиться от оператора if и добавления, если вы сделаете это так.
byte[] foobar = ..;
int value = (foobar[10] & 0xff);
Таким образом, Java не интерпретирует байт как отрицательное число и также переворачивает знаковый бит в целое число.
Ответ 3
Использование ints обычно лучше, чем использование shorts, потому что java в любом случае использует 32-битные значения (даже для байтов, если только в массиве), поэтому использование ints позволит избежать ненужного преобразования в/из коротких значений в байт-коде.
Ответ 4
Вероятно, лучше всего использовать целое число, а не байт. Он имеет номер, позволяющий номерам, превышающим 128, без накладных расходов на создание специального объекта для замены байта.
Это также предлагают люди умнее меня (всех)
Ответ 5
Лучшим способом выполнения бит-манипуляции/беззнаковых байтов является использование int. Несмотря на то, что они подписаны, у них есть много запасных бит (всего 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.
Ответ 6
Я знаю, что это очень поздний ответ, но я столкнулся с этим вопросом, пытаясь сделать то же самое. Проблема заключается в попытке определить, есть ли байт Java > 127.
Простое решение:
if((val & (byte)0x80) != 0) { ... }
Если реальная проблема составляет > 128 вместо этого, просто добавив еще одно условие к тому, что оператор if сделает трюк.
Ответ 7
Думаю, вы могли бы просто использовать их для хранения. Не очень эффективный, но действительно единственный вариант, помимо некоторых усилий, которые я видел.