Каков наилучший способ обойти тот факт, что все байты Java подписаны?


в Java нет такой вещи, как байт без знака.

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

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

7 55

7 ответов:

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

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

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

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

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

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

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

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

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

лучший способ сделать бит манипуляции / беззнаковые байты через использование ints. несмотря на то, что они подписаны, у них есть много запасных битов (всего 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 примитивно.

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

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

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

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

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