public void Update(IFrequencyTable freqs, int symbol) { var range = _high - _low + 1; long total = freqs.GetTotal(); long symLow = freqs.GetLow(symbol); long symHigh = freqs.GetHigh(symbol); var newLow = _low + symLow * range / total; var newHigh = _low + symHigh * range / total - 1; _low = newLow; _high = newHigh; while (((_low ^ _high) & _halfRange) == 0) { Shift(); _low = ((_low << 1) & _stateMask); _high = ((_high << 1) & _stateMask) | 1; } while ((_low & ~_high & _quarterRange) != 0) { Underflow(); _low = (_low << 1) ^ _halfRange; _high = ((_high ^ _halfRange) << 1) | _halfRange | 1; } }
public int Read(IFrequencyTable freqs) { long total = freqs.GetTotal(); var range = _high - _low + 1; var offset = _code - _low; var value = ((offset + 1) * total - 1) / range; var start = 0; var end = freqs.GetSymbolLimit(); while (end - start > 1) { var middle = (start + end) >> 1; if (freqs.GetLow(middle) > value) { end = middle; } else { start = middle; } } var symbol = start; Update(freqs, symbol); return(symbol); }