diff --git a/bitutilities.py b/bitutilities.py index eb6cc58..2275c12 100644 --- a/bitutilities.py +++ b/bitutilities.py @@ -163,6 +163,7 @@ def binary_subtraction(minuend: BasicRegister, subtrahend: BasicRegister) -> Bas :return: Register containing the difference. :rtype: BasicRegister """ + subtrahend = BasicRegister(subtrahend.memory) subtrahend.negate() difference: BasicRegister @@ -176,6 +177,29 @@ def binary_subtraction(minuend: BasicRegister, subtrahend: BasicRegister) -> Bas return difference +def binary_subtraction_second_complement(minuend: BasicRegister, subtrahend: BasicRegister) \ + -> tuple[BasicRegister, bool]: + """ + Subtracts the second term from the first in binary using seconds' complement. + + :param BasicRegister minuend: Register to subtract from. + :param BasicRegister subtrahend: Register to subtract by. + + :return: Register containing the difference. + :rtype: BasicRegister + """ + subtrahend = BasicRegister(subtrahend.memory) + subtrahend.negate() + + subtrahend = binary_sum(*align_registers(subtrahend, BasicRegister([True]))) + + difference: BasicRegister + final_carry: bool + difference, final_carry = binary_sum_with_carry(minuend, subtrahend) + + return difference, final_carry + + def align_registers(*registers: BasicRegister) -> tuple[BasicRegister, ...]: """ Aligns registers by the length of the bigger one. @@ -201,6 +225,18 @@ def format_device_state_table(table) -> str: return pt.get_string() +def get_mantice_complement(register: BasicRegister) -> BasicRegister: + memory: list[bool] = list(register.memory) + invertion_enabled: bool = False + + for i, v in list(enumerate(memory))[::-1]: + memory[i] = v ^ invertion_enabled + + if v: + invertion_enabled = True + + return BasicRegister(deque(memory)) + def binary_multiplication_method_1(first_term: BasicRegister, second_term: BasicRegister) \ -> tuple[BasicRegister, list[list[str]]]: """ @@ -238,8 +274,6 @@ def binary_multiplication_method_1(first_term: BasicRegister, second_term: Basic rg1.right_shift() ct.decrement() - # print(ct.memory) - data_table[-1].append(list(map(str, [i, rg1, rg2, rg3, ct, "RG2 := RG1[1].r(RG2)\nRG1 := 0.r(RG1)\nCT := CT - 1"]))) return BasicRegister(rg1.memory + rg2.memory), data_table @@ -366,3 +400,88 @@ def binary_multiplication_method_4(first_term: BasicRegister, second_term: Basic data_table[-1].append(list(map(str, [i, rg1, rg2, rg3, "RG2 := l(RG2).0\nRG3 := 0.r(RG3)"]))) return BasicRegister(deque(list(rg1.memory)[:-1])), data_table + +def binary_division_method_1(first_term: BasicRegister, second_term: BasicRegister) \ + -> tuple[BasicRegister, list[list[str]]]: + """ + Divides first term by the second term containing binary numbers using first method. + + :param: BasicRegister first_term: Register being divided. + :param: BasicRegister second_term: Register being divided by. + + :return: Register containing the division result. + :rtype: BasicRegister + """ + + first_term, second_term = align_registers(first_term, second_term) + n: int = len(first_term) + + rg1 = BasicRegister(deque([False, False]) + second_term.memory) + rg2 = BasicRegister(deque([False, False]) + first_term.memory) + rg3 = BasicRegister(deque([True] * (n+1))) + + data_table = [["iter", "RG3", "RG2", "RG1", "MicroOperations"]] + i = 0 + + data_table.append([]) + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, "-"]))) + + while rg3.memory[0]: + i += 1 + data_table.append([]) + + if rg2.memory[0]: + rg2 = binary_sum(rg2, rg1) + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, "RG2 := RG2 + RG1"]))) + else: + rg2, _ = binary_subtraction_second_complement(rg2, rg1) + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, "RG2 := RG2 - RG1"]))) + + rg3.left_shift(rg2.memory[0]) + rg2.left_shift() + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, f"RG3 := l(RG3).RG2[{n+2}]\nRG2 := l(RG2).0"]))) + + return BasicRegister(deque(list(rg3.memory)[1:])), data_table + +def binary_division_method_2(first_term: BasicRegister, second_term: BasicRegister) \ + -> tuple[BasicRegister, list[list[str]]]: + """ + Divides first term by the second term containing binary numbers using second method. + + :param: BasicRegister first_term: Register being divided. + :param: BasicRegister second_term: Register being divided by. + + :return: Register containing the division result. + :rtype: BasicRegister + """ + + first_term, second_term = align_registers(first_term, second_term) + n: int = len(first_term) + + rg1 = BasicRegister(deque([False]) + second_term.memory + deque([False]*n)) + rg2 = BasicRegister(deque([False]) + first_term.memory + deque([False]*n)) + rg3 = BasicRegister(deque([True] * (n+1))) + + data_table = [["iter", "RG3", "RG2", "RG1", "MicroOperations"]] + i = 0 + carry = False + + data_table.append([]) + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, "-"]))) + + while rg3.memory[0]: + i += 1 + data_table.append([]) + + if rg2.memory[0]: + rg2, carry = binary_sum_with_carry(rg2, rg1) + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, "RG2 := RG2 + RG1"]))) + else: + rg2, carry = binary_subtraction_second_complement(rg2, rg1) + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, "RG2 := RG2 - RG1"]))) + + rg3.left_shift(carry) + rg1.right_shift() + data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, f"RG3 := l(RG3).SM[p]\nRG1 := 0.r(RG1)"]))) + + return BasicRegister(deque(list(rg3.memory)[1:])), data_table diff --git a/main.py b/main.py index ab005b9..6187570 100644 --- a/main.py +++ b/main.py @@ -32,7 +32,15 @@ def input_handler(first_register: bu.BasicRegister, second_register: bu.BasicReg case _: print("Such method does not exist, try again.") case "d": - pass + match input("Choose method to use (1-2):\n>>> "): + case "1": + # Warn about development + print("WARNING: this method is still being figured out, wrong results to be expected for now.") + result, data_table = bu.binary_division_method_1(first_register, second_register) + print(f"Division:\n{bu.format_device_state_table(data_table)}\nResult: {result}") + case "2": + result, data_table = bu.binary_division_method_2(first_register, second_register) + print(f"Division:\n{bu.format_device_state_table(data_table)}\nResult: {result}") case "q": exit() case _: