I'm aiming to write some unsigned numbers to a network packet.
The shortest way I calculate to write this information is what I call "bitstacks". This may be a term already coined.
Basically, I have a variable size vector of unsigned integers. Each time an (unreliable) network packet of a type is received, it contains one of those unsigned integers. That unsigned integer is deleted from the vector.
After all the unreliable packets have been received, there's a high chance there are some numbers left - a different message type is formed, and sent with all the numbers. I need to copy all the numbers in the vector to a memory address, copying only the bits that can be different per number.
I calculate this by finding the lowest power of 2 from the maximum limit of the range (aka the highest unsigned integer expected).
For example, if the packets are limited from 0-NumPackets...
unsigned char NearestSize = (unsigned char)ceil(log((double)NumPackets)/(8*log(2.0)));
...where 8 is number of bits in a byte, and 2.0 is because each bit is worth the next power of 2 (casted to a double for non-ambiguous log()).
if the maximum number is 31, the bits can reach 00011111. So there's always an excess 3 bits. By shifting the packet numbers to "fill the gap", I save 3 bits per number, and being there is potentially thousands of numbers being sent back, this'll quickly multiply. In fact, in 3 numbers, you've already saved an entire byte. That's 66% compression :)
So I know how many bits to write, where to read it from. That's all I need to read the variable properly; but how do I write it? The best approximation is annoyingly close to what I want, but still fails to meet the mark.
See the full draft code here:
http://paste.pocoo.org/show/0TnEFukAsPJntrZhVADf/
Sorry about the format of the code. I appreciate this is a challenge even for seasoned C++ers.
Thanks in advance, SC.