def compute_with_numbers(self, a: Number, b: Number) -> Number:
     if a.sign != b.sign:
         return Number(a.digits, a.sign) + (-b)
     elif a.sign == b.sign == Sign.negative:
         return (-b) - (-a)
     elif a < b:
         return Number((b - a).digits, Sign.negative)
     res = []
     carry = 0
     b_len = len(b)
     a_len = len(a)
     for i in range(max(a_len, b_len)):
         diff = (0 if i >= a_len else a[i]) - (0 if i >= b_len else b[i]) - carry
         if diff < 0:
             diff += CommandContext.Base
             carry = 1
         else:
             carry = 0
         res.append(diff)
     real_res_len = len(res)
     for digit in res[::-1]:
         if digit == 0:
             real_res_len -= 1
         else:
             break
     if real_res_len <= 1:
         return Number([res[0]])
     else:
         return Number(res[:real_res_len])
Exemple #2
0
def test_negative_numbers_subtraction(token_stack):
    token_stack.push(Number([4, 5], Sign.negative))
    token_stack.push(Number([2, 6], Sign.negative))
    subtraction = Subtraction()
    result = subtraction.compute()
    assert result.sign == Sign.positive
    assert len(result.digits) == 1
    assert result.digits[0] == 8
Exemple #3
0
def test_leading_zero_removal(token_stack):
    token_stack.push(Number([3, 5]))
    token_stack.push(Number([1, 5]))
    subtraction = Subtraction()
    result = subtraction.compute()
    assert result.sign == Sign.positive
    assert len(result.digits) == 1
    assert result.digits[0] == 2
Exemple #4
0
def test_simple_carry(token_stack):
    token_stack.push(Number([3, 5]))
    token_stack.push(Number([5, 3]))
    subtraction = Subtraction()
    result = subtraction.compute()
    assert result.sign == Sign.positive
    assert len(result.digits) == 2
    assert result.digits[0] == 8
    assert result.digits[1] == 1
Exemple #5
0
def test_opposite_signs_numbers_subtraction2(token_stack):
    token_stack.push(Number([2, 1], Sign.positive))
    token_stack.push(Number([3, 1], Sign.negative))
    subtraction = Subtraction()
    result = subtraction.compute()
    assert result.sign == Sign.positive
    assert len(result.digits) == 2
    assert result.digits[0] == 5
    assert result.digits[1] == 2
Exemple #6
0
 def compute_with_numbers(self, a: Number, b: Number) -> Number:
     if not b:
         raise DividingByZeroError()
     b_copy = Number(b.digits.copy())
     q = Number([0])
     r = Number(a.digits.copy())
     while r >= b_copy:
         n = len(r) - len(b_copy)
         n_digits = [0 for _ in range(n)]
         n_digits.extend(b_copy.digits)
         n_number = Number(n_digits)
         if n_number > r:
             n -= 1
             del n_number.digits[0]
         c = CommandContext.Base - 1
         cal = n_number * Number([c])
         while cal > r:
             c -= 1
             cal = n_number * Number([c])
         c_digits = [0 for _ in range(n)]
         c_digits.append(c)
         q = q + Number(c_digits)
         r = r - cal
     if a.sign != b.sign:
         q.sign = Sign.negative
     return q
Exemple #7
0
    def compute_with_numbers(self, a: Number, b: Number) -> Number:
        if a.sign != b.sign:
            if b.sign == Sign.negative:
                return a - (-b)
            else:
                return b - (-a)

        a_digits = a.digits.copy()
        b_digits = b.digits.copy()

        while len(a_digits) < len(b_digits):
            a_digits.append(0)

        while len(b_digits) < len(a_digits):
            b_digits.append(0)

        res_digits = [x + y for x, y in zip(a_digits, b_digits)]

        carry_over = 0
        for i in range(len(res_digits)):
            res_digits[i] += carry_over
            carry_over = res_digits[i] // CommandContext.Base
            res_digits[i] = res_digits[i] % CommandContext.Base

        if carry_over != 0:
            res_digits.append(carry_over)
        else:
            while len(res_digits) > 1 and res_digits[-1] == 0:
                res_digits.pop()

        return Number(res_digits, a.sign)
Exemple #8
0
 def compute_with_numbers(self, a: Number, b: Number) -> Number:
     res = Number([0])
     for offset, i in enumerate(a.digits):
         digits = [0 for _ in range(offset)]
         carry_over = 0
         for index, j in enumerate(b.digits):
             compute = i * j + carry_over
             digits.append(compute % CommandContext.Base)
             carry_over = compute // CommandContext.Base
         if carry_over != 0:
             digits.append(carry_over)
         else:
             while len(digits) > 1 and digits[-1] == 0:
                 digits.pop()
         res = res + Number(digits, Sign.positive)
     if a.sign != b.sign:
         res.sign = Sign.negative
     return res
Exemple #9
0
def test_two_digits_subtraction(token_stack, ten):
    token_stack.push(Number([0, 5]))
    token_stack.push(ten)
    subtraction = Subtraction()
    result = subtraction.compute()
    assert result.sign == Sign.positive
    assert len(result.digits) == 2
    assert result.digits[0] == 0
    assert result.digits[1] == 4
Exemple #10
0
 def compute_with_numbers(self, a: Number, b: Number) -> Number:
     if not b:
         return Number([1])
     if not b.sign:
         raise NegativePowerError()
     if b == Number([1]):
         return Number(a.digits, a.sign)
     elif not b[0] % 2:
         return self.compute_with_numbers(a * a, b / Number([2]))
     else:
         return a * self.compute_with_numbers(
             a * a, (b - Number([1])) / Number([2]))
Exemple #11
0
def test_two_power_four(token_stack, two, four):
    token_stack.push(two)
    token_stack.push(four)
    power = Power()
    result = power.compute()
    assert result == Number([6, 1])
Exemple #12
0
def test_one_power_two(token_stack, one, two):
    token_stack.push(one)
    token_stack.push(two)
    power = Power()
    result = power.compute()
    assert result == Number([1])
Exemple #13
0
def large_number():
    return Number([2, 6, 3, 8, 7, 6])
Exemple #14
0
def minus_ninety_nine():
    return Number([9, 9], Sign.negative)
Exemple #15
0
def eight():
    return Number([8])
Exemple #16
0
def two():
    return Number([2])
Exemple #17
0
def minus_one():
    return Number([1], Sign.negative)
Exemple #18
0
def hundred():
    return Number([0, 0, 1])
Exemple #19
0
def zero_large():
    return Number([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Exemple #20
0
def test_eight_power_four(token_stack, eight, four):
    token_stack.push(eight)
    token_stack.push(four)
    power = Power()
    result = power.compute()
    assert result == Number([6, 9, 0, 4])
Exemple #21
0
def one():
    return Number([1])
Exemple #22
0
def test_ninety_nine_power_five(token_stack, ninety_nine, five):
    token_stack.push(ninety_nine)
    token_stack.push(five)
    power = Power()
    result = power.compute()
    assert result == Number([9, 9, 4, 0, 0, 9, 9, 0, 5, 9])
Exemple #23
0
def four():
    return Number([4])
Exemple #24
0
def test_four_power_zero(token_stack, zero, four):
    token_stack.push(four)
    token_stack.push(zero)
    power = Power()
    result = power.compute()
    assert result == Number([1])
Exemple #25
0
def ten():
    return Number([0, 1])
Exemple #26
0
def test_minus_one_power_four(token_stack, minus_one, four):
    token_stack.push(minus_one)
    token_stack.push(four)
    power = Power()
    result = power.compute()
    assert result == Number([1])
Exemple #27
0
def nine_nine():
    return Number([9, 9, 9, 9, 9, 9, 9, 9, 9])
Exemple #28
0
def test_minus_one_power_five(token_stack, minus_one, five):
    token_stack.push(minus_one)
    token_stack.push(five)
    power = Power()
    result = power.compute()
    assert result == Number([1], Sign.negative)
Exemple #29
0
def zero():
    return Number([0])
Exemple #30
0
def five():
    return Number([5])