Reputation: 21
cross posting from https://github.com/bitvecto-rs/bitvec/issues/163
I'm trying to create compact binary representations of integers, with minimal padding. I'm currently reaching for BitVec, but that's not necessarily the best solution. I'm actually putting together a simple arithmetic encoding scheme for lossy encoding of floats and integers, based on this reference. For that I need to do the following-
for a more concrete example, say i have the input value 100106
, then I can convert that to a binary string using format
println!("{:b}", 100106_usize);
// "011000011100001010"
if I naively convert the usize
directly to a BitVec
, then the value is padded
let bit_vec = BitVec::from_element(100106_usize);
println!("{:b}", bit_vec);
// "[0101000011100001100000000000000000000000000000000000000000000000]"
i was playing around with bitwise operators and pushing bits into a Vec<bool>
. That seems like it would work, but also like i was reinventing the wheel. I suspect i'm missing something obvious.
To be clear the binary representation needs some padding, but of variable width, since i need a fixed number of bits that can represent the largest possible value in a given range.
For example, if i wanted to represent values in the range (-10000..10000), then i can represent this by mapping to (0..20000), and the number of bits i need to store the largest possible value is ceil(log2(20000)) == 18
. So to 'encode' into this representation i need to add 10000, and then encode as exactly 18 bits (i'm taking this example straight from the reference at https://libdccl.org/codecs.html)
Upvotes: 0
Views: 1398
Reputation: 21
answer provided on the github issue:
use bitvec::prelude::*;
let num = 100_106usize;
let raw = num.view_bits::<Lsb0>();
let bits = raw.iter_ones().last().unwrap_or(bitvec::mem::bits_of::<usize>() - 1);
let bv = raw[..= bits].to_bitvec();
Upvotes: 0