digits even though we might be off by one, and re-adjust the range to give us as much room as possible. The decoder will be following the same steps so it will know when it needs to do this to keep in sync. // this goes just before the end of Encode() above if (range < 1000) { EmitDigit(); EmitDigit(); range = 100000 - low; } Base 10 was used in this example, but a real implementation would just use binary, with the full range of the native integer data type. Instead of 10000 and 1000 you would likely use hexadecimal constants such as 0x1000000 and 0x10000. Instead of emitting a digit at a time you would emit a byte at a time and use a byte-shift operation instead of multiplying by 10. Decoding uses exactly the same algorithm with the addition of keeping track of the current code value consisting of the digits read from the compressor. Instead of emitting the top digit of low you just throw it away, but you also shift out the top digit of code and shift in a new digit read from the compressor. Use AppendDigit below instead of EmitDigit. int code = 0; int low = 0; int range = 1; void InitializeDecoder() { AppendDigit(); // with this example code, only 1 of these is actually needed AppendDigit(); AppendDigit(); AppendDigit(); AppendDigit(); } void AppendDigit() { code = (code % 10000) * 10 + ReadNextDigit(); low = (low % 10000) * 10; range *= 10; } void Decode(int start, int size, int total) // Decode is same as Encode with EmitDigit replaced by AppendDigit { // adjust the range based on the symbol interval range /= total; low += start * range; range *= size; // check if left-most digit is same throughout range while (low / 10000 == (low + range) / 10000) AppendDigit(); // readjust range - see reason for this below if (range < 1000) { AppendDigit(); AppendDigit(); range = 100000 - low; } } In order to determine which probability intervals to apply, the decoder needs to look at the current value of code within the interval [low, low+range) and decide which symbol this represents. void Run() { int start = 0; int size; int total = 10; InitializeDecoder(); // need to get range/total >0 while (start < 8) // stop when receive EOM { int v = GetValue(total);