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

StackOverflow https://stackoverflow.com/questions/11088

  •  08-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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 есть одно беззнаковое число фиксированной точности.Это голец примитивный.

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top