Converting integer to BitSet in Rust gives unexpected values

Converting integer to BitSet in Rust gives unexpected values

I am getting an unexpected result converting integers into a BitSet from crate bit_set.

use bit_set::BitSet;

fn main() {
    let v: i32 = 7;
    let bytes = v.to_be_bytes();
    let bs = BitSet::from_bytes(&bytes);
    println!("{bs:?}")
}

yields {29,30,31}. I was hoping for {0,1,2} corresponding to the three set bits in 7. The bits are being interpreted in the reverse order.

I'd like to initialize the BitSet with an integer because I'm iterating through integer values with Gosper's Hack. The BitSet would be a convenient way of representing the result for use elsewhere in my code.

Since my naive approach to initializing the BitSet isn't right, how can I fix it, or otherwise accomplish what I'm after?

Answer

Instead of converting i32 to bytes and passing it to BitSet::from_bytes, you can construct the BitSet manually by iterating through the bits:

use bit_set::BitSet;

fn main() {
    let v: i32 = 7;
    let mut bs = BitSet::new();

    for i in 0..32 {
        if (v & (1 << i)) != 0 {
            bs.insert(i);
        }
    }

    println!("{bs:?}"); // Output: {0, 1, 2}
}

If You’re Using Gosper’s Hack

Since you’re iterating through integers with Gosper’s Hack (e.g., generating combinations of k bits), this solution is compatible:

fn int_to_bitset(v: u32) -> BitSet {
    let mut bs = BitSet::new();
    for i in 0..32 {
        if (v & (1 << i)) != 0 {
            bs.insert(i);
        }
    }
    bs
}

Then just call int_to_bitset(v) for each value of v.

Enjoyed this question?

Check out more content on our blog or follow us on social media.

Browse more questions