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-
- truncate and scale input values to an unsigned integer value (this part isn't a problem)
- generate the most compact possible binary representation of that integer
- concatenate the bits with other encoded numbers
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)
answer provided on the github issue: