From c0aebf14d2968a8364041e5c61d3dfcbf8a040d3 Mon Sep 17 00:00:00 2001 From: dymik739 Date: Mon, 17 Jun 2024 21:07:51 +0300 Subject: [PATCH] add square root extraction implementation --- bitutilities.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 8 +++-- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/bitutilities.py b/bitutilities.py index 0c778e4..4dbdeaa 100644 --- a/bitutilities.py +++ b/bitutilities.py @@ -100,6 +100,18 @@ class Counter(BasicRegister): return any(self.memory) +def negated(memory: deque[bool]) -> deque[bool]: + """ + Returns negated memory chunk. + + :param deque[bool] memory: Memory chunk to be negated. + + :return: Negated memory chunk. + :rtype: deque[bool] + """ + return deque([not value for value in memory]) + + def get_memory(variable_name: str) -> deque[bool]: """ Reads user input to be used as a memory array. @@ -472,3 +484,68 @@ def binary_division_method_2(first_term: BasicRegister, second_term: BasicRegist 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 + +def binary_square_root(first_term: BasicRegister) \ + -> tuple[BasicRegister, list[list[str]]]: + """ + Extracts the square root of first term. + + :param: BasicRegister first_term: Register for square root extraction. + + :return: Register containing the division result and the state table of a virtual + device that extracted the square root of the given term. + :rtype: tuple[BasicRegister, list[list[str]]] + """ + + n: int = len(first_term) + i = 0 + + rga = BasicRegister(deque([False]*n)) + rgb = BasicRegister(deque([False]*(n+2))) + rgc = BasicRegister(first_term.memory) + ct = Counter(n) + + data_table = [["iter", "RGA", "RGB", "RGC", "CT", "MicroOperations"]] + + data_table.append([]) + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "-"]))) + + # two initial shifts + rgb.left_shift(rgc.memory[0]) + rgc.left_shift() + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := l(RGB).RGC[0]\nRGC := l(RGC).0"]))) + + rgb.left_shift(rgc.memory[0]) + rgc.left_shift() + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := l(RGB).RGC[0]\nRGC := l(RGC).0"]))) + + # initial inverted addition + rgb = binary_sum(rgb, BasicRegister(negated(rga.memory) + deque([True, True]))) + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := RGB + !(RGA).11"]))) + + while ct.non_zero(): + data_table.append([]) + i += 1 + + rga.left_shift(not rgb.memory[0]) + rgb.left_shift(rgc.memory[0]) + rgc.left_shift() + + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGA := l(RGA).!(RGB[0])\nRGB := l(RGB).RGC[0]\nRGC := l(RGC).0"]))) + + rgb.left_shift(rgc.memory[0]) + rgc.left_shift() + + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := l(RGB).RGC[0]\nRGC := l(RGC).0"]))) + + if rgb.memory[0]: + rgb = binary_sum(rgb, BasicRegister(rga.memory + deque([True, True]))) + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := RGB + RGA.11"]))) + else: + rgb = binary_sum(rgb, BasicRegister(negated(rga.memory) + deque([True, True]))) + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := RGB + !(RGA).11"]))) + + ct.decrement() + data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "CT := CT - 1"]))) + + return rga, data_table diff --git a/main.py b/main.py index 5d45226..1a745a4 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ user_input = [] def process_command(symbol): global operation, method - if symbol.lower() in "asmdq": + if symbol.lower() in "asmdrq": operation = symbol elif operation == "m" and symbol in "1234": method = symbol @@ -65,6 +65,10 @@ def perform_operation(first_register: bu.BasicRegister, second_register: bu.Basi operation, method = "", "" case _: pass + case "r": + result, data_table = bu.binary_square_root(first_register) + print(f"\nSquare root:\n{bu.format_device_state_table(data_table)}\nResult: {result}") + operation, method = "", "" case "q": exit(0) @@ -96,7 +100,7 @@ def input_handler(first_register: bu.BasicRegister, second_register: bu.BasicReg # print() if operation == "": raw_user_input = input("Choose the operation:\n" - "[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit\n" + + "[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [r]oot, [q]uit\n" + prompt_text + " > ") elif operation == "m": raw_user_input = input("Choose method to use (1-4):\n" + prompt_text + " > ")