Побитовое И, Побитовое Включающее ИЛИ вопрос, в Java - PullRequest
10 голосов
/ 18 февраля 2009

У меня есть несколько строк кода в проекте, и я не вижу значения ...

buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80);

Он читает файловый буфер из файла, хранящегося в байтах, а затем передает его в буфер [i], как показано, но я не понимаю, какова общая цель, какие-либо идеи?

Спасибо

Ответы [ 7 ]

9 голосов
/ 18 февраля 2009

Как уже говорилось в других ответах, (currentByte & 0x7F) | (currentByte & 0x80) эквивалентно (currentByte & 0xFF). JLS3 15.22.1 говорит, что это повышен до int:

Когда оба операнда оператора &, ^ или | имеют тип, который обратимый (§5.1.8) к примитиву целочисленный тип, двоичное число продвижение сначала выполняется на операнды (§5.6.2). Тип побитовое выражение оператора является повышенный тип операндов.

потому что JLS3 5.6.2 говорит, что когда currentByte имеет тип byte и 0x7F является int (и это так), тогда оба операнда переводятся в int.

Следовательно, buffer будет массивом типа элемента int или шире.

Теперь, выполняя & 0xFF для int, мы эффективно отображаем исходный диапазон byte -128..127 в диапазон без знака 0..255, например, операция, часто используемая потоками java.io. .

Вы можете увидеть это в действии в следующем фрагменте кода. Обратите внимание: чтобы понять, что здесь происходит, вы должны знать, что Java хранит целочисленные типы, кроме char, в качестве дополнения 2 к значениям .

byte b = -123;
int r = b;
System.out.println(r + "= " + Integer.toBinaryString(r));
int r2 = b & 0xFF;
System.out.println(r2 + "= " + Integer.toBinaryString(r2));

Наконец, для реального примера посмотрите Javadoc и реализацию java.io.ByteArrayInputStream метода *1038*:

/**
 * Reads the next byte of data from this input stream. The value 
 * byte is returned as an <code>int</code> in the range 
 * <code>0</code> to <code>255</code>. If no byte is available 
 * because the end of the stream has been reached, the value 
 * <code>-1</code> is returned. 
 */
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
4 голосов
/ 18 февраля 2009
 (currentByte & 0x7F) | (currentByte & 0x80)

эквивалентно

 currentByte & (0x7F | 0x80)

, что равно

 currentByte & 0xFF

, что точно так же, как

 currentByte

Редактировать: я смотрел только на правую сторону задания, и я все еще думаю, что эквивалентность верна.

Однако, похоже, что код хочет преобразовать подписанный байт в больший тип, интерпретируя байт как беззнаковый.

Есть ли более простой способ преобразовать подписанный байт в unsigned в Java?

3 голосов
/ 18 февраля 2009

Я думаю, что кто-то слишком много думал здесь. Это просто не правильно.

У меня есть только одно замечание

  • Первоначальный автор был обеспокоен тем, что во время выполнения заменит байт на собственное целое число со знаком (предположительно, 32-разрядное), и явно пытается нам что-то сказать о том, что бит знака является "особенным"?

Это оставленный код. Разве вы не знаете, что вы на рыбном беге? Каков тип буфера?

2 голосов
/ 18 февраля 2009

Результат побитовой операции И имеет 1 для тех битов, где оба бита равны 1, в то время как результат побитовой операции ИЛИ a для тех битов, где один из битов бота равен 1.

Итак, пример оценки для значения 0x65:

  01100101 0x65
& 01111111 0x7F
===============
  01100101 0x65

  01100101 0x65
& 10000000 0x80
===============
  00000000 0x00

  01100101 0x65
| 00000000 0x00
===============
  01100101 0x65
2 голосов
/ 18 февраля 2009

Сложная побитовая логика совершенно лишняя.

for (int i = 0; i < buffer.length; i++) {
    buffer[i] = filebuffer[currentPosition + i] & 0xff;
}

делает то же самое. Если буфер объявлен как массив байтов, вы можете даже пропустить & 0xff, но, к сожалению, объявление не отображается.

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

0 голосов
/ 20 февраля 2009

Оказывается, файл, из которого считывался байт, был в битовой нотации со знаком и имел другую длину, поэтому было необходимо выполнить эту задачу, чтобы разрешить его расширение до типа java int при сохранении его правильный знак:)

0 голосов
/ 18 февраля 2009

Хорошая вещь об этих видах логических операций: вы можете попробовать каждую возможную комбинацию (все 256 из них) и убедиться, что получили ответ, который ожидали.

...