예제 #1
0
class _Amount:
    def __init__(self, fraction_digits: int, precision: int):
        self._ctx = Context(prec=precision, rounding=ROUND_HALF_EVEN)

        self._fraction_digits = fraction_digits
        self._precision = precision
        self._quantizer = self._ctx.create_decimal(1).scaleb(-fraction_digits)

        self._value = self._ctx.create_decimal(0)

    def deserialize(self, serialized_value):
        self._value = (
            self._ctx.create_decimal(serialized_value)
            .scaleb(-self._fraction_digits)
            .quantize(self._quantizer)
        )
        return self

    def serialize(self) -> int:
        return int(self._value.scaleb(self._fraction_digits))

    def set(self, value: Decimal):
        self._value = self._ctx.create_decimal(value).quantize(self._quantizer)
        return self

    def clone(self):
        raise NotImplementedError

    def __str__(self):
        return str(self._value)

    def __imul__(self, other):
        operand = other._value if isinstance(other, Amount) else other
        value = self._ctx.multiply(self._value, operand)
        return self.set(value)

    def __itruediv__(self, other):
        operand = other._value if isinstance(other, Amount) else other
        value = self._ctx.divide(self._value, operand)
        return self.set(value)

    def __mul__(self, other):
        return self.clone().__imul__(other)

    def __truediv__(self, other):
        return self.clone().__itruediv__(other)

    def __iadd__(self, other):
        operand = other._value if isinstance(other, Amount) else other
        value = self._ctx.add(self._value, operand)
        return self.set(value)

    def __add__(self, other):
        return self.clone().__iadd__(other)
예제 #2
0
    return x


txt = open('../data/don_quixote.txt', 'r').read()
src = source(txt)
letters, count = map(list, zip(*src))
probs = [x / sum(count) for x in count]
p = min(probs)
k = ceil(-log(p, 2) + 2)

l = 1000
for _ in range(1000):
    i = min(randrange(len(txt)), len(txt) - l)
    str = txt[i:i + l]

    c = arithmetic_encode(str, src, k)
    print(c)

    ctx = Context()
    d = dict(zip(letters, probs))
    pr = reduce(lambda x, y: ctx.multiply(x, Decimal(d[y])), str, Decimal(1))
    expected_length = ceil(-ctx.divide(pr.ln(ctx), Decimal(2).ln(ctx))) + 1
    actual_length = len(c)
    assert (actual_length <= expected_length)

    dec = arithmetic_decode(c, src, k, len(str))
    print(dec)

    assert (dec == str)