Побитовые операции, сравнивая u32 с байтовым массивом - PullRequest
1 голос
/ 22 марта 2020

Допустим, у меня есть значение 1025 в качестве байтового массива и значение 1030 в качестве размера. Как бы я go сравнил, если байтовый массив больше, меньше или равен без его десериализации?

Я полностью застрял, я предполагаю, что самый простой способ - получить самые большие байты массива байтов, его положение, затем сдвиньте биты u32 и посмотрите, установлены ли какие-либо биты в байте, если не массив байтов.

Короче говоря, я хочу написать некоторые функции, чтобы можно было решить, если a> b, a Чтобы использовать пример кода

fn is_greater(a: &[u8], b: usize) -> bool {
    // a is LE, so reverse and get the largest bytes
    let c = a.iter()
        .enumerate()
        .rev()
        .filter_map(|(i, b)| ( if *b != 0 { return Some((i, *b)); } else { None }))
        .collect::<Vec<(usize, u8)>>();

    for (i, be) in c {
        let k = (b >> (i * 8)) & 255;
        println!("{}, {}", be, k);

        return be as usize > k
    }

    false
}

РЕДАКТИРОВАТЬ: Должно быть уточнено, массив байтов может быть любым целым числом, целым числом без знака или с плавающей запятой. Просто любое целочисленное bincode :: serialize может сериализовать.

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

1 Ответ

2 голосов
/ 22 марта 2020

Нет необходимости во всех этих дополнительных шагах. Основная проблема c заключается в том, чтобы узнать, является ли целое число, закодированное в байтовом массиве, little endian, big endian или native endian. Зная это, вы можете использовать usize::from_??_bytes для преобразования массива фиксированного размера в целое число; используйте TryFrom -trait , чтобы получить массив фиксированного размера из среза.

fn is_greater(b: &[u8], v: usize) -> Result<bool, std::array::TryFromSliceError> {
    use std::convert::TryFrom;
    Ok(usize::from_le_bytes(<[u8; 8]>::try_from(b)?) > v)
}

Эта функция вернет ошибку, если срез байтов меньше 8 байтов, в этом случае нет способа построить usize; Вы также можете преобразовать в u32 или даже u16, увеличить значение до usize и затем выполнить сравнение. Также обратите внимание, что этот пример использует from_le_bytes, предполагая, что срез байтов содержит целое число, закодированное как little endian.

...