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 бит влево. занять позицию третьего байта int (считая справа). Это связано с массивом байтов, хранящим байты в форматеbig-endian , где MSB стоит на первом месте. Следующий байт сдвигается только на 8 бит, чтобы занять позицию второго байта, а последний вообще не нужно сдвигать, так как он уже находится в первой точке байта.
Почему newInt & 0x00800000? Каково значение 0x00800000?
Ну
0x80
это еще одна битовая маска чтобы получить MSB определенного байта.0x00800000
соответствует MSB третьего байта (то есть байта вbyteArray[0]
, который был сдвинут на 16 бит, оставшихся в предыдущем процессе). Это также соответствует MSB всего 24-битного значения.Почему if-else основан на положительном и неотрицательном результате вышеупомянутой операции?
Определение того, является ли MSB 24-битного значения 1 или 0, покажет нам, является ли оно отрицательным или положительным числом, соответственно, в дополнении two нотация.
Каково значение 0xFF000000 и 0x00FFFFFF?
Если число отрицательно в его 24-битном представлении, мы также хотим, чтобы оно было отрицательным как 32-битное значение в дополнении двух, поэтому мы должны заполнить 4-й и последний байт
0b11111111
(0xFF) с помощью оператора OR.
Если он уже был положительным, то четвертый байт может быть 0x00, при этом следующие 3 байта совпадают с исходным 24-битным значением-выполняется маскировка с помощью0x00FFFFFF
.