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

В Java нет такого понятия, как беззнаковый байт.

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

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

Ответов (7)

Решение

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

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

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

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

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

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

Лучший способ манипулировать битами / байтами без знака - использовать 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 .

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

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

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

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

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

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

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

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