diff --git a/bitutilities.py b/bitutilities.py index 35bc7a3..33a9986 100644 --- a/bitutilities.py +++ b/bitutilities.py @@ -70,6 +70,32 @@ class BasicRegister: return shifted_bits +class Counter: + """ + The Counter represents a hardware register specifically designed for countdowns. + + :param int value: Initial numeric value this Counter holds. + """ + + def __init__(self, value: int): + self.memory: deque[bool] = deque([i == "1" for i in bin(value)[2:]]) + + def __repr__(self) -> str: + return f"Memory: {[int(value) for value in self.memory]}" + + def __str__(self) -> str: + return f"Memory: {[int(value) for value in self.memory]}" + + def __len__(self) -> int: + return len(self.memory) + + def decrement(self): + self.memory = binary_subtraction(self, BasicRegister([False] * (len(self.memory) - 1) + [True])).memory + + def non_zero(self) -> bool: + return any(self.memory) + + def get_memory(variable_name: str) -> list[bool]: """ Reads user input to be used as a memory array. @@ -182,3 +208,114 @@ def align_registers(*registers: BasicRegister) -> tuple[BasicRegister, ...]: """ required_size: int = max(map(len, registers)) return tuple(reg.adjusted_by_size(required_size) for reg in registers) + + +def binary_multiplication_method_1(first_term: BasicRegister, second_term: BasicRegister) -> BasicRegister: + """ + Multiplies two terms containing binary numbers using first method. + + :param BasicRegister first_term: First register to multiply. + :param BasicRegister second_term: Second register to multiply. + + :return: Register containing the product. + :rtype: BasicRegister + """ + first_term, second_term = align_registers(first_term, second_term) + n: int = len(first_term) + + rg1 = BasicRegister([False] * n) + rg2 = BasicRegister(first_term.memory) + rg3 = BasicRegister(second_term.memory) + ct = Counter(n) + + while ct.non_zero(): + if rg2.memory[n-1]: + rg1 = binary_sum(rg1, rg3) + + rg2.right_shift(rg1.memory[n-1]) + rg1.right_shift() + ct.decrement() + + return BasicRegister(list(rg1.memory) + list(rg2.memory)) + +def binary_multiplication_method_2(first_term: BasicRegister, second_term: BasicRegister) -> BasicRegister: + """ + Multiplies two terms containing binary numbers using second method. + + :param BasicRegister first_term: First register to multiply. + :param BasicRegister second_term: Second register to multiply. + + :return: Register containing the product. + :rtype: BasicRegister + """ + first_term, second_term = align_registers(first_term, second_term) + n: int = len(first_term) + + rg1 = BasicRegister([False] * (2*n)) + rg2 = BasicRegister(first_term.memory) + rg3 = BasicRegister([False] * n + list(second_term.memory)) + + while any(rg2.memory): + if rg2.memory[n-1]: + rg1 = binary_sum(rg1, rg3) + + rg2.right_shift() + rg3.left_shift() + + return rg1 + +def binary_multiplication_method_3(first_term: BasicRegister, second_term: BasicRegister) -> BasicRegister: + """ + Multiplies two terms containing binary numbers using third method. + + :param BasicRegister first_term: First register to multiply. + :param BasicRegister second_term: Second register to multiply. + + :return: Register containing the product. + :rtype: BasicRegister + """ + first_term, second_term = align_registers(first_term, second_term) + n: int = len(first_term) + + rg1 = BasicRegister([False] * n) + rg2 = BasicRegister(list(first_term.memory) + [False]) + rg3 = BasicRegister([False] * (n+1) + list(second_term.memory)) + ct = Counter(n) + + while ct.non_zero(): + if rg2.memory[0]: + result: list[bool] = list(binary_sum(BasicRegister(rg2.memory + rg1.memory), rg3).memory) + rg2 = BasicRegister(result[:n+1]) + rg1 = BasicRegister(result[n+1:]) + + rg2.left_shift(rg1.memory[0]) + rg1.left_shift() + ct.decrement() + + return BasicRegister((list(rg2.memory) + list(rg1.memory))[:-1]) + +def binary_multiplication_method_4(first_term: BasicRegister, second_term: BasicRegister) -> BasicRegister: + """ + Multiplies two terms containing binary numbers using fourth method. + + :param BasicRegister first_term: First register to multiply. + :param BasicRegister second_term: Second register to multiply. + + :return: Register containing the product. + :rtype: BasicRegister + """ + first_term, second_term = align_registers(first_term, second_term) + n: int = len(first_term) + + rg1 = BasicRegister([False] * (2*n+1)) + rg2 = BasicRegister(first_term.memory) + rg3 = BasicRegister([False] + list(second_term.memory) + [False] * n) + + while any(rg2.memory): + if rg2.memory[0]: + rg1 = binary_sum(rg1, rg3) + + rg2.left_shift() + rg3.right_shift() + + return BasicRegister(list(rg1.memory)[:-1]) diff --git a/main.py b/main.py index 27f58ec..de91651 100644 --- a/main.py +++ b/main.py @@ -16,7 +16,17 @@ def input_handler(first_register: bu.BasicRegister, second_register: bu.BasicReg case "s": print(f"Subtraction:\n{bu.binary_subtraction(first_register, second_register)}") case "m": - pass + match input("Choose method to use (1-4):\n>>> "): + case "1": + print(f"Multiplication: {bu.binary_multiplication_method_1(first_register, second_register)}") + case "2": + print(f"Multiplication: {bu.binary_multiplication_method_2(first_register, second_register)}") + case "3": + print(f"Multiplication: {bu.binary_multiplication_method_3(first_register, second_register)}") + case "4": + print(f"Multiplication: {bu.binary_multiplication_method_4(first_register, second_register)}") + case _: + print("Such method does not exist, try again.") case "d": pass case "q":