diff --git a/src/mult-test.py b/src/mult-test.py new file mode 100644 index 0000000..4887d00 --- /dev/null +++ b/src/mult-test.py @@ -0,0 +1,27 @@ +import multiply as mlt + +top_value = int("0b" + input("Top value (in binary): "), 2) +m = int(input("Method: ")) + +total_iterations = (top_value + 1) ** 2 +print(f"Total test amount: {top_value + 1}^2 = {total_iterations}") + +errors = [] + +for x in range(top_value): + for y in range(top_value): + n = max([len(bin(i)[2:]) for i in (x, y)]) + expected_result = mlt.al(bin(x*y)[2:], 2*n) + + _, r = mlt.multiply(n, x, y, m) + + if r == expected_result: + print(f"{str(x*top_value+y).rjust(len(str(total_iterations)))}/{total_iterations}", end = "\r") + else: + errors.append([x, y, expected_result, r]) + print(f"Failed at {x}*{y}; expected {expected_result} but got {r}!") + +if len(errors) == 0: + print("Testing finished, no miscalculations detected.\nIt's safe to use!") +else: + print("Testing failed with {len(errors)} errors.") diff --git a/src/multiply.py b/src/multiply.py index 124c1ad..7c8f749 100644 --- a/src/multiply.py +++ b/src/multiply.py @@ -8,52 +8,90 @@ def align_binary_to_right(value, size): al = align_binary_to_right -def multiply(x, y, method): +def multiply(n, x, y, method): + ''' + this method can be used to: + - get step-by-step binary multiplication data using different methods; + - get just the end result of binary multiplication; + + it takes 4 arguments: + n - (int) base register bit depth + x - (int) value for X operand + y - (int) value for Y operand + method - (int) which method to use to perform multiplication + + it returns 2 items: + - (list) table with step-by-step operations and descriptions + - (str) binary representation of the result + + Methods fully supported: №4 + ''' + if method == 4: - n = len(bin(x)[2:]) # base registry bit length, usually written as n - # every table line has registers like so: RG1, RG3, RG2 - data_table = [[["0"*(2*n+1), "0" + bin(y)[2:] + "0"*n, bin(x)[2:], "-"]]*2] + data_table = [[["0", "0"*(2*n+1), "0" + al(bin(y)[2:], n) + "0"*n, al(bin(x)[2:], n), "-"]]*2] - while int('0b' + data_table[-1][-1][2], 2) != 0: + # iteration number + i = 0 + + while int('0b' + data_table[-1][-1][3], 2) != 0: data_table.append([]) + i += 1 - if data_table[-2][-1][2][0] == "1": + if data_table[-2][-1][3][0] == "1": data_table[-1].append([ - al(bin(int("0b"+data_table[-2][-1][0], 2) + int("0b"+data_table[-2][-1][1], 2))[-(2*n+1):], 2*n+1), # RG1 + RG3 - data_table[-2][-1][1], + i, + al(bin(int("0b"+data_table[-2][-1][1], 2) + int("0b"+data_table[-2][-1][2], 2))[-(2*n+1):], 2*n+1), # RG1 + RG3 data_table[-2][-1][2], + data_table[-2][-1][3], "RG1+RG3" ]) data_table[-1].append([ - data_table[-1][-1][0], - '0' + data_table[-1][-1][1][:-1], # 0.r(RG3) - data_table[-1][-1][2][1:] + '0', # l(RG2).0 + i, + data_table[-1][-1][1], + '0' + data_table[-1][-1][2][:-1], # 0.r(RG3) + data_table[-1][-1][3][1:] + '0', # l(RG2).0 "0.r(RG3), l(RG2).0" ]) else: data_table[-1].append([ - data_table[-2][-1][0], - '0' + data_table[-2][-1][1][:-1], # 0.r(RG3) - data_table[-2][-1][2][1:] + '0', # l(RG2).0 + i, + data_table[-2][-1][1], + '0' + data_table[-2][-1][2][:-1], # 0.r(RG3) + data_table[-2][-1][3][1:] + '0', # l(RG2).0 "0.r(RG3), l(RG2).0" ]) - return data_table + return data_table, data_table[-1][-1][1][:-1] + if __name__ == "__main__": - x = int("0b" + input("X: "), 2) - y = int("0b" + input("Y: "), 2) + # a fully functional reference + # implementation for this library + # is provided below + + raw_x = input("X: ") + raw_y = input("Y: ") + + if len(raw_x) == len(raw_y): + n = len(raw_x) + else: + n = int(input("n: ")) + + x = int("0b" + raw_x, 2) + y = int("0b" + raw_y, 2) + method = int(input("Method: ")) - dt = multiply(x, y, method) + + dt, result = multiply(n, x, y, method) from lib.prettytable import PrettyTable pt = PrettyTable() - pt.field_names = ["RG1", "RG3", "RG2", "Operations"] + pt.field_names = ["Iteration", "RG1", "RG3", "RG2", "Operations"] - for i in dt[1:]: + for i in dt: for j in range(len(i)): if j+1 == len(i): pt.add_row(i[j], divider = True) @@ -61,3 +99,4 @@ if __name__ == "__main__": pt.add_row(i[j]) print(pt) + print(f"Result: {result}")