2008-08-14 15 views
53

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

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

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

ответ

18

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

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

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

+46

Значительно проще и эффективнее делать int value = (foobar [10] &0xFF); – 2009-05-02 07:33:43

+8

Возможно, но я хотел, чтобы мой код был как можно более ясным и поучительным. Кроме того, я не знаю, что '&' делает для отрицательных целые числа в Java (по крайней мере, не без googling), поэтому я играл в это безопасно. – pauldoo 2009-05-04 10:47:50

+1

Почему бы и сделать что-то другое для отрицательных чисел. И логическая операция работает на отдельных битах, она знает, проверяет или ухаживает, положительное, отрицательное или любое другое значение. – 2011-06-16 02:53:47

-1

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

0

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

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

0

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

1

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

77

@pauldoo

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

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

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

0

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

Самое простое решение:

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

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