public int read() throws IOException {
            // Translate from coding range scale to frequency table scale
            long total = freq.total();
            Preconditions.checkState(total < MAX_TOTAL, "Cannot decode symbol because total is too large");
            long range = high - low + 1;
            long offset = code - low;
            long value = ((offset + 1) * total - 1) / range;

            // A kind of binary search
            int start = 0;
            int end = freq.symbolCount();
            while (end - start > 1) {
                int middle = (start + end) >>> 1;
                if (freq.low(middle) > value)
                    end = middle;
                else
                    start = middle;
            }

            int symbol = start;
            update(symbol);
            return symbol;
        }
Must be called at the end of the stream of input symbols, otherwise the output data
cannot be decoded properly.
indexr-segment/src/main/java/io/indexr/compress/ArthmeticCoder.java