Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I split a 16-bit value into two 8-bit values?

Tags:

rust

I have u16 value and want to convert it into two u8 values to put it into u8 array, the same as described here.

0000000000000011 -> 00000000    and    00000011

How would I do that in a convenient way?

like image 709
raiym Avatar asked Nov 03 '25 17:11

raiym


1 Answers

Putting the answers provided by @apilat and @Anton into code:

Bit Shifting - verbose style

This can be accomplished in a couple of different ways. I actually think that bit shifting is a little clearer, as no thought needs to be given to whether I need to worry about endianness.

Spelling out each:

fn shift_verbose_split_u16(short_16: u16) -> [u8; 2] {

    let high_byte: u8 = (short_16 >> 8) as u8;
    let low_byte: u8 = (short_16 & 0xff) as u8;

    return [high_byte, low_byte];
}

Bit Shifting - idiomatic style

The above code can be reduced to a one-line function:

fn shift_idiomatic_split_u16(short_16: u16) -> [u8; 2] {
    [(short_16 >> 8) as u8, (short_16 & 0xff) as u8]
}

Using to_be_bytes()

Using to_be_bytes() certainly is the simplest solution. Using this solution, you have to realize that you really want to use the big-endian call, regardless of the underlying cpu's architecture:

let [high, low] = short_16.to_be_bytes();

Grouping the code into one file:

fn main() {
    let short_16: u16 = 0x3f23;
    
    // verbose bit shifting
    let [high, low] = shift_verbose_split_u16(short_16);
    assert_eq!(high, 0x3f);
    assert_eq!(low, 0x23);

    // idiomatic bit shifting
    let [high, low] = shift_idiomatic_split_u16(short_16);
    assert_eq!(high, 0x3f);
    assert_eq!(low, 0x23);

    let [high, low] = short_16.to_be_bytes();
    assert_eq!(high, 0x3f);
    assert_eq!(low, 0x23);

    println!("High: {:#0x?}, Low: {:#0x?}", high, low);   
}

fn shift_verbose_split_u16(short_16: u16) -> [u8; 2] {

    let high_byte: u8 = (short_16 >> 8) as u8;
    let low_byte: u8 = (short_16 & 0xff) as u8;

    return [high_byte, low_byte];
}

fn shift_idiomatic_split_u16(short_16: u16) -> [u8; 2] {
    [(short_16 >> 8) as u8, (short_16 & 0xff) as u8]
}

Output:

High: 0x3f, Low: 0x23
like image 143
Gardener Avatar answered Nov 05 '25 15:11

Gardener



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!