Вопрос

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

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

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

Спасибо

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

Решение

Как уже говорилось в других ответах, (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 и реализацией read метод java.io.ByteArrayInputStream:

/**
 * 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;
}

Другие советы

 (currentByte & 0x7F) | (currentByte & 0x80)

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

 currentByte & (0x7F | 0x80)

что равно

 currentByte & 0xFF

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

 currentByte

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

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

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

Мне кажется, здесь кто-то слишком много думал.Это просто неправильно.

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

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

Это код, оставшийся позади.Если только вы не знаете, что у вас подозрительное время выполнения?Какой вообще тип «буфера»?

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

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

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

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

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

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

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

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

  01100101 0x65
| 00000000 0x00
===============
  01100101 0x65

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

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

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