-1

When loading a slice of bitvec as u8 I am not getting the expected result when bitvec order does not match big/little endian. Here's example code showing the issue:

use bitvec::prelude::*; use rand::Rng; let mut rng = rand::rng(); let mut bv: BitVec<u8, Msb0> = BitVec::with_capacity(1000); for _ in 0..1000 { bv.push(rng.random()); } let idx_to_print = 159; let bslice = &bv[idx_to_print..idx_to_print+8]; let val: u8 = bslice.load_le(); println!("Bitvec: {:?}, Orig: {:b}",bslice, val); 

This gives me result:

Bitvec: BitSlice<u8, bitvec::order::Msb0> { addr: 0x5e32ef0bb243, head: 111, bits: 8 } [1, 1, 1, 1, 1, 0, 0, 1], Orig: 11110011 

Now things are fine when bitvec order and big/little endian are aligned. And there's no reason I should be using this call. BUT - shouldn't the bits here simply be reversed? They are not.

10
  • 1
    "shouldn't the bits here simply be reversed?" why do you think so? Endianness does not affect how individual bits are stored, it's about multi-byte values and how their bytes are stored. Commented Aug 23 at 10:16
  • Can you talk more. If this is normal/expected behavior, could you explain what this behavior is i.e. how/why the two things differ in the above code. Commented Aug 23 at 13:25
  • 1
    @cafce25 Msb0 in bitvec talks about the bit ordering, not the byte ordering. Commented Aug 23 at 20:44
  • @ste_kwr Be aware that load_le() is talking about byte order, and Msb0 is talking about bit order. At least from how I understand the docs. Commented Aug 23 at 20:46
  • 1
    Well either way, look at my answer. If you use Lsb0 with load_le, it works. If you use Msb0 with load_be, it works. So clearly they somehow influence each other. Commented Aug 23 at 21:06

1 Answer 1

2

I'm not sure what exactly the intended behavior of bitvec should be, but the result of this code strikes me as strange:

use bitvec::prelude::*; fn main() { // Aligned let bv = bits![u8, Msb0; 0, 0, 0, 0, 1, 1, 1, 1]; println!("{} -> {:08b}", bv, bv.load_le::<u8>()); // Unaligned let bv = bits![u8, Msb0; 0, 0, 0, 0, 0, 1, 1, 1, 1]; let bv = &bv[1..]; println!("{} -> {:08b}", bv, bv.load_le::<u8>()); } 
[0, 0, 0, 0, 1, 1, 1, 1] -> 00001111 [0, 0, 0, 0, 1, 1, 1, 1] -> 10000111 

So I suspect a bug / missed corner case in bitvec. I created a bug report here.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.