Каков наилучший способ обойти тот факт, что все байты Java подписаны?
в Java нет такой вещи, как байт без знака.
работая с некоторым низкоуровневым кодом, иногда вам нужно работать с байтами, которые имеют значения без знака больше 128, что заставляет Java интерпретировать их как отрицательное число из-за того, что MSB используется для знака.
какой хороший способ обойти это? (Говоря не использовать Java не вариант)
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-оператор будет делать трюк.