Извлечение 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);
}
Этот способ потребляет входной массив. Скорее всего, это может быть сделано лучше, если немного поиграть.