Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a bool array into a byte array

Tags:

rust

How do I convert a bool array into a byte array?

I would like the resulting vector to have 1/8th the length of the input vector.

Like this

let a = [false; 160];
let b: [u8; 20] = ???

I guess I can make a for-loop and do some arithmetic, but I wonder if there is a simpler way of doing it.

like image 904
Thorkil Værge Avatar asked Jun 10 '26 19:06

Thorkil Værge


2 Answers

As an alternative to the crate-based solutions, the "hand-rolled" version isn't too difficult to implement, and avoids the allocations:

    let mut b = [0u8;20];
    for (idx, bit) in a.into_iter().enumerate() {
        let byte = idx / 8;
        let shift = 7 - idx % 8;
        b[byte] |= (bit as u8) << shift;
    }

The issue making this generic is that the current const generics don't support arithmetics on constants.

In nightly with generic_const_expr, it's possible for the thing to work on arbitrary input sizes (this incomplete implementation will panic on incomplete trailing bytes):

#![feature(generic_const_exprs)]

fn to_bits<const N: usize>(bools: [bool;N]) -> [u8;N/8] {
    let mut out = [0;N/8];
    for (idx, bit) in bools.into_iter().enumerate() {
        let byte = idx / 8;
        let shift = 7 - idx % 8;
        out[byte] |= (bit as u8) << shift;
    }
    out
}

fn main() {
    let mut a = [false; 160];
    a[42] = true;
    let b = to_bits(a);
    println!("{:?}", b);
}

though I think bitvec also has a BitArray type which might allow doing this without allocations as well.

like image 52
Masklinn Avatar answered Jun 12 '26 10:06

Masklinn


This works and doesn't require a new dependency.

    let mut b = [0u8;20];
    for i in 0..160 {
        b[i / 8] |= u8::from(a[i]) << (i % 8);
    }
like image 40
Thorkil Værge Avatar answered Jun 12 '26 12:06

Thorkil Værge



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!