Compare commits

...

4 Commits

9 changed files with 144 additions and 11 deletions

View File

@@ -20,13 +20,13 @@ al = align_binary_to_left
def shift_left(rg, fill_bit = 0): def shift_left(rg, fill_bit = 0):
return rg[1:] + fill_bit return rg[1:] + str(fill_bit)
l = shift_left l = shift_left
def shift_right(rg, fill_bit = 0): def shift_right(rg, fill_bit = 0):
return fill_bit + rg[:-1] return str(fill_bit) + rg[:-1]
r = shift_right r = shift_right
@@ -37,14 +37,20 @@ def sum_supplementary_codes(x, y, size):
sum = sum_supplementary_codes sum = sum_supplementary_codes
def sum_supplementary_codes_with_overspill(x, y, size): def sum_supplementary_codes_right_align(x, y, size):
return ar(bin(int("0b"+x, 2) + int("0b"+y, 2))[2:], size)
rsum = sum_supplementary_codes_right_align
def sum_supplementary_codes_with_overflow(x, y, size):
result = bin(int("0b"+x, 2) + int("0b"+y, 2))[2:] result = bin(int("0b"+x, 2) + int("0b"+y, 2))[2:]
if len(result) > size: if len(result) > size:
return al(result, size), '1' return al(result, size), '1'
else: else:
return al(result, size), '0' return al(result, size), '0'
sump = sum_supplementary_codes_with_overspill sump = sum_supplementary_codes_with_overflow
def invert_bit(b): def invert_bit(b):
@@ -57,3 +63,15 @@ def invert_bit(b):
exit(1) exit(1)
inv = invert_bit inv = invert_bit
def xor(x, y):
if len(x) == len(y):
result = ''
for i in zip(x, y):
if x != y:
result += '1'
else:
result += '0'
return result

View File

@@ -24,4 +24,4 @@ for x in range(top_value):
if len(errors) == 0: if len(errors) == 0:
print("Testing finished, no miscalculations detected.\nIt's safe to use!") print("Testing finished, no miscalculations detected.\nIt's safe to use!")
else: else:
print("Testing failed with {len(errors)} errors.") print(f"Testing failed with {len(errors)} errors.")

View File

@@ -1,3 +1,9 @@
import bitutils as bu
# this needs to be replaced at some point, because:
# - it uses old notation for align operation, which contradicts with
# modern instruction sets, thus making it easily confusable with
# the bu.al() operation which aligns bits to the left
def align_binary_to_right(value, size): def align_binary_to_right(value, size):
if "b" in value: if "b" in value:
result = value.split("b")[1] result = value.split("b")[1]
@@ -15,19 +21,62 @@ def multiply(n, x, y, method):
- get just the end result of binary multiplication; - get just the end result of binary multiplication;
it takes 4 arguments: it takes 4 arguments:
n - (int) base register bit depth n - (int) base register bit length
x - (int) value for X operand x - (int) value for X operand
y - (int) value for Y operand y - (int) value for Y operand
method - (int) which method to use to perform multiplication method - (int) which method to use to perform multiplication
it returns 2 items: it returns 2 items:
- (list) table with step-by-step operations and descriptions - (list) table with step-by-step operations and descriptions (table format
- (str) binary representation of the result depends on the chosen method)
- (str) binary representation of the result (method-independant)
Methods fully supported: №4 Methods fully supported:
- №2 (passed mult-test.py with 10 bits)
- №4 (passed mult-test.py with 12 bits)
''' '''
if method == 4: if method == 2:
# every table line has registers like so: RG1, RG3, RG2
data_table = [[["0", "0"*(2*n), "0"*n + bu.ar(bin(y)[2:], n), bu.ar(bin(x)[2:], n), "-"]]*2]
# iteration number
i = 0
while int('0b' + data_table[-1][-1][3], 2) != 0:
data_table.append([])
i += 1
if data_table[-2][-1][3][-1] == "1":
data_table[-1].append([
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
bu.rsum(data_table[-2][-1][1], data_table[-2][-1][2], 2*n),
data_table[-2][-1][2],
data_table[-2][-1][3],
"RG1+RG3"
])
data_table[-1].append([
i,
data_table[-1][-1][1],
bu.l(data_table[-1][-1][2]), # l(RG3).0
bu.r(data_table[-1][-1][3]), # 0.r(RG2)
"0.r(RG2), l(RG3).0"
])
else:
data_table[-1].append([
i,
data_table[-2][-1][1],
bu.l(data_table[-2][-1][2]), # l(RG3).0
bu.r(data_table[-2][-1][3]), # 0.r(RG2)
"0.r(RG2), l(RG3).0"
])
return data_table, data_table[-1][-1][1]
elif method == 4:
# every table line has registers like so: RG1, RG3, RG2 # every table line has registers like so: RG1, RG3, RG2
data_table = [[["0", "0"*(2*n+1), "0" + al(bin(y)[2:], n) + "0"*n, al(bin(x)[2:], n), "-"]]*2] data_table = [[["0", "0"*(2*n+1), "0" + al(bin(y)[2:], n) + "0"*n, al(bin(x)[2:], n), "-"]]*2]
@@ -66,6 +115,19 @@ def multiply(n, x, y, method):
return data_table, data_table[-1][-1][1][:-1] return data_table, data_table[-1][-1][1][:-1]
def table_to_text(dt):
from lib.prettytable import PrettyTable
pt = PrettyTable()
pt.field_names = ["Iteration", "RG1", "RG3", "RG2", "Operations"]
for i in dt:
for j in range(len(i)):
if j+1 == len(i):
pt.add_row(i[j], divider = True)
else:
pt.add_row(i[j])
return pt.get_string()
if __name__ == "__main__": if __name__ == "__main__":
# a fully functional reference # a fully functional reference
@@ -87,6 +149,7 @@ if __name__ == "__main__":
dt, result = multiply(n, x, y, method) dt, result = multiply(n, x, y, method)
'''
from lib.prettytable import PrettyTable from lib.prettytable import PrettyTable
pt = PrettyTable() pt = PrettyTable()
pt.field_names = ["Iteration", "RG1", "RG3", "RG2", "Operations"] pt.field_names = ["Iteration", "RG1", "RG3", "RG2", "Operations"]
@@ -99,4 +162,6 @@ if __name__ == "__main__":
pt.add_row(i[j]) pt.add_row(i[j])
print(pt) print(pt)
'''
print(table_to_text(dt))
print(f"Result: {result}") print(f"Result: {result}")

1
src/www/bitutils.py Symbolic link
View File

@@ -0,0 +1 @@
../bitutils.py

1
src/www/divide.py Symbolic link
View File

@@ -0,0 +1 @@
../divide.py

1
src/www/lib Symbolic link
View File

@@ -0,0 +1 @@
../lib/

1
src/www/multiply.py Symbolic link
View File

@@ -0,0 +1 @@
../multiply.py

23
src/www/web-divide.py Normal file
View File

@@ -0,0 +1,23 @@
import os
import sys
from divide import divide, table_to_text
print(os.environ, file = sys.stderr)
raw_params = list(map(lambda x: x.split("="), os.environ['QUERY_STRING'].split("&")))
baked_params = {k:v for (k, v) in raw_params}
bp = baked_params
if "x" in bp and "y" in bp and "m" in bp:
x = int("0b" + bp['x'], 2)
y = int("0b" + bp['y'], 2)
m = int(bp['m'])
dt, result = divide(max(list(map(len, [bp['x'], bp['y']]))), x, y, m)
print(f"Content-Type: text/plain; charset=UTF-8\r\n"
f"\r\n"
f"{table_to_text(dt)}\r\n"
f"Result: {result}")
else:
print("Content-Type: text/plain; charset=UTF-8\r\n\r\nCheck your input!")

23
src/www/web-multiply.py Normal file
View File

@@ -0,0 +1,23 @@
import os
import sys
from multiply import multiply, table_to_text
print(os.environ, file = sys.stderr)
raw_params = list(map(lambda x: x.split("="), os.environ['QUERY_STRING'].split("&")))
baked_params = {k:v for (k, v) in raw_params}
bp = baked_params
if "x" in bp and "y" in bp and "m" in bp:
x = int("0b" + bp['x'], 2)
y = int("0b" + bp['y'], 2)
m = int(bp['m'])
dt, result = multiply(max(list(map(len, [bp['x'], bp['y']]))), x, y, m)
print(f"Content-Type: text/plain; charset=UTF-8\r\n"
f"\r\n"
f"{table_to_text(dt)}\r\n"
f"Result: {result}")
else:
print("Content-Type: text/plain; charset=UTF-8\r\n\r\nCheck your input!")