3

Меня интересует новый проект IoT под названием OpenBCI, который в основном представляет собой ЭЭГ с открытым кодом для чтения и обработки волн мозга и других биодатов. В своем docs они утверждают, что данные, передаваемые по эфиру (через RFDuino), отправляют 24-битные данные. Для того, чтобы преобразовать 24-битные значения в 32-разрядных целых чисел, они предлагают следующий Java-дружественную Processing код: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?

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

+0

Эта последняя часть является неясным способом подписи-расширения, ветка else - это не-op. Более очевидным будет 'newInt = (newInt << 8) >> 8' – harold

ответ

8

Почему безопасно предположить, что на входе 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 основан на положительном и отрицательном результате вышеуказанной операции?

Определение старший бит 24-разрядного значения, является ли 1 или 0 будет сказать нам, если это отрицательное или положительное число, соответственно, в two's complement нотации.

В чем смысл 0xFF000000 и 0x00FFFFFF?

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

+0

Удивительный, внушительный ответ @James Buck (+1) - спасибо! Просто любопытно, если бы я реализовал это на Java, и мне нужен единичный тест, чтобы подтвердить, работает ли это или нет, где я могу найти 24-битные знаковые целые числа и соответствующие им 32-разрядные значения, чтобы проверить результаты теста с? :-) Еще раз спасибо! – smeeb

+0

@smeeb Ну, вы можете выбрать любое случайное 24-битное число, поместить их в двоичный код дополнения до десятичного конвертера, например [this] (http://www.exploringbinary.com/twos-complement-converter/). Затем вы можете поместить тот же двоичный номер в 3-байтовый массив, и вышеуказанный код должен преобразовать его в 32-битное целое с тем же значением, что и калькулятор. Этот код гарантирует, что любое 24-битное значение сохранит его значение при преобразовании в 32-битный формат. –

 Смежные вопросы

  • Нет связанных вопросов^_^