24- в 32-битное преобразование в Java

Меня интересует новый проект IoT под названием OpenBCI, который в основном представляет собой ЭЭГ с открытым исходным кодом для чтения и обработки мозговых волн и других биоданных. В своих документах они утверждают, что данные, передаваемые по радиоканалу (через RFDuino), отправляют 24-битные данные. Чтобы преобразовать 24-разрядные значения в 32-разрядные целые числа со знаком, они предлагают следующий дружественный к Java код обработки:

int interpret24bitAsInt32(byte[] byteArray) {
    int newInt = (
        ((0xFF & byteArray[0]) << 16) |
        ((0xFF & byteArray[1]) << 8) |
        (0xFF & byteArray[2])
    );

    if ((newInt & 0x00800000) > 0) {
        newInt |= 0xFF000000;
    } else {
        newInt &= 0x00FFFFFF;
    }

    return newInt;
}

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

int newInt = (
    ((0xFF & byteArray[0]) << 16) |
    ((0xFF & byteArray[1]) << 8) |
    (0xFF & byteArray[2])
);
  • Почему можно предположить, что на входе есть 3 байта?
  • Какое значение имеет 0xFF значение?
  • Какова цель сдвига влево (<<)?

Второй сегмент тоже немного загадочный:

if ((newInt & 0x00800000) > 0) {
    newInt |= 0xFF000000;
} else {
    newInt &= 0x00FFFFFF;
}
  • Зачем newInt & 0x00800000? Какое значение имеет 0x00800000?
  • Почему if-else на основе положительного и неотрицательного результата вышеуказанной операции?
  • Какое значение имеет 0xFF000000 а также 0x00FFFFFF?

Я думаю, что с этой функцией происходит много волнений и магии, которые я хотел бы понять лучше!

1 ответ

Решение

Почему можно предположить, что на входе есть 3 байта?

24 бита / 8 бит = 3 байта

Какое значение имеет значение 0xFF?

Это немного маска. 0b11111111 в двоичном В этой ситуации это используется как быстрый способ преобразовать значение байта в int.

Какова цель сдвига влево (<<)?

Как только значение int было получено в предыдущей инструкции, оно сдвигается на 16 бит влево, чтобы занять позицию третьего байта целого числа (считая справа). Это связано с тем, что байтовый массив хранит байты в формате с прямым порядком байтов, где MSB стоит первым. Следующий байт сдвигается только на 8 бит, чтобы занять позицию второго байта, и последний не нужно сдвигать вообще, поскольку он уже находится в первой позиции байта.

Почему newInt & 0x00800000? Каково значение 0x00800000?

Что ж 0x80 это другая битовая маска для получения MSB определенного байта. 0x00800000 соответствует старшему биту третьего байта (т.е. байту в byteArray[0] это было сдвинуто на 16 бит в предыдущем процессе). Это также соответствует MSB всего 24-битного значения.

Почему if-else основан на положительном и неотрицательном результате вышеуказанной операции?

Определение, является ли MSB 24-битного значения 1 или 0, скажет нам, является ли это отрицательным или положительным числом, соответственно, в двоичной записи дополнения.

Каково значение 0xFF000000 и 0x00FFFFFF?

Если число является отрицательным в его 24-битном представлении, мы также хотим, чтобы оно было отрицательным как 32-битное значение в дополнении к двум, поэтому мы должны заполнить 4-й и последний байт 0b11111111 (0xFF) используя оператор OR.
Если он уже был положительным, то четвертый байт может быть 0x00, при этом следующие 3 байта совпадают с исходным 24-битным значением, что достигается маскированием с помощью 0x00FFFFFF,

Другие вопросы по тегам