Bitwise ops generic over u8, u16, u32, u64

Is there snippets of Rust code that regardless of whether x is an u8, u16, u32, or u64 can check if:

  • most significant two bits of x is '00'
  • most significant two bits of x is '01'
  • most significant two bits of x is '10'
  • most significant two bits of x is '11'
  • result of setting most significant two bits of x to '00'

?

This ought to be possible somehow using the PrimInt trait (perhaps also using methods from its supertraits) from the num crate.

1 Like
type TheType = u32;

pub fn most_sig_is_00(value: TheType) -> bool {
    let mask = TheType::reverse_bits(0b11);
    (value & mask) == 0
}

pub fn most_sig_is_01(value: TheType) -> bool {
    let mask = TheType::reverse_bits(0b11);
    (value & mask) == TheType::reverse_bits(0b10)
}

pub fn most_sig_is_10(value: TheType) -> bool {
    let mask = TheType::reverse_bits(0b11);
    (value & mask) == TheType::reverse_bits(0b01)
}

pub fn most_sig_is_11(value: TheType) -> bool {
    let mask = TheType::reverse_bits(0b11);
    (value & mask) == TheType::reverse_bits(0b11)
}

pub fn set_most_sig_00(value: TheType) -> TheType {
    let mask = !TheType::reverse_bits(0b11);
    value & mask
}
2 Likes
use num::PrimInt;

fn get_two_most_significant_bits<I: PrimInt>(i: I) -> u8 {
    let mask = (!I::zero()).unsigned_shr(2); // 00111…111
    (i & !mask).rotate_left(2).to_u8().unwrap()
}

fn set_two_most_significant_bits<I: PrimInt>(i: I, bits: u8) -> I {
    let mask = (!I::zero()).unsigned_shr(2); // 00111…111
    (i & mask) | I::from(bits & 0b11).unwrap().rotate_right(2)
}

#[test]
fn test() {
    let x = 0b_0111_1111_1111_1111_u16;
    assert_eq!(get_two_most_significant_bits(x), 0b01);
    assert_eq!(set_two_most_significant_bits(x, 0b_00), 0b_0011_1111_1111_1111_u16);
    let x = 0b_1011_1111_1111_1111_u16 as i16;
    assert_eq!(get_two_most_significant_bits(x), 0b10);
    assert_eq!(set_two_most_significant_bits(x, 0b_01), 0b_0111_1111_1111_1111_u16 as i16);
}

Rust Playground

1 Like