Как лучше всего обойти тот факт, что ВСЕ байты Java подписаны?
Вопрос
В 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.
Я думаю, вы могли бы просто использовать короткое замыкание для их хранения.Не очень эффективно, но это единственный вариант, если не считать титанических усилий, которые я видел.