Извлечение 7-битного целого числа со знаком из байта u8

Я использую протокол Human Interface Device для получения данных с внешнего устройства. Библиотека, которую я использую, возвращает массив байтов ([u8; 64]) который я хочу извлечь i7 (которые будут i8 в Rust) от одного байта.

Байт, которым я хочу манипулировать, содержит две разные части информации:

  • 1 бит за что-то
  • 7 других битов (которые я должен декодировать как целое число со знаком) для другой вещи.

Вы знаете, что я могу сделать, чтобы достичь этого?

3 ответа

Решение

Используя ящикbitreader Я был в состоянии правильно декодировать целое число со знаком 7 бит.

let mut bit_reader = BitReader::new(buffer);
let first_useless_bit: u8 = bit_reader.read_u8(1).unwrap();
let extracted_value: i8 = bit_reader.read_i8(7).unwrap();

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

fn main() {
    let byte = 0xFFu8;
    let byte2 = (byte & 0b0111_1111) as i8;
    println!("{}", byte2);
}

Если вы хотите превратить массив u8 в вектор i8 игнорируя наиболее значимый бит, вы можете сделать это следующим образом:

fn main() {
    let array_unsigned = [1u8, 2, 3]; // this will work for 64 values too
    let vec_signed: Vec<i8> = array_unsigned.into_iter()
        .map(|&e| if e <= 127 { e as i8 } else { (e - 128) as i8 }).collect();

    println!("{:?}", vec_signed);
}

Этот способ потребляет входной массив. Скорее всего, это может быть сделано лучше, если немного поиграть.

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