Compare commits
10 Commits
1ab5b67c77
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 462536043d | |||
| 44457b1849 | |||
| 31ec6b2697 | |||
| 24b62d109a | |||
| 3338a75114 | |||
| 0df9dd3016 | |||
| 49dbc9a164 | |||
| a04084d8e3 | |||
| 0530d4b54f | |||
| 8019753a12 |
1
src/bdmconv.py
Symbolic link
1
src/bdmconv.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
binary-to-decimal-mantice-converter.py
|
||||||
14
src/binary-to-decimal-mantice-converter.py
Normal file
14
src/binary-to-decimal-mantice-converter.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
def convert(x):
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for p, i in enumerate(x):
|
||||||
|
if i == '1':
|
||||||
|
result += 2**(-p-1)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
# sample implementation
|
||||||
|
if __name__ == "__main__":
|
||||||
|
x = input("Enter mantice: ")
|
||||||
|
r = convert(x)
|
||||||
|
print(f"Result: {r}")
|
||||||
77
src/bitutils.py
Normal file
77
src/bitutils.py
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
def align_binary_to_right(value, size):
|
||||||
|
if "b" in value:
|
||||||
|
result = value.split("b")[1]
|
||||||
|
else:
|
||||||
|
result = str(value)
|
||||||
|
|
||||||
|
return result[-size:].rjust(size, "0")
|
||||||
|
|
||||||
|
ar = align_binary_to_right
|
||||||
|
|
||||||
|
def align_binary_to_left(value, size):
|
||||||
|
if "b" in value:
|
||||||
|
result = value.split("b")[1]
|
||||||
|
else:
|
||||||
|
result = str(value)
|
||||||
|
|
||||||
|
return result[-size:].ljust(size, "0")
|
||||||
|
|
||||||
|
al = align_binary_to_left
|
||||||
|
|
||||||
|
|
||||||
|
def shift_left(rg, fill_bit = 0):
|
||||||
|
return rg[1:] + str(fill_bit)
|
||||||
|
|
||||||
|
l = shift_left
|
||||||
|
|
||||||
|
|
||||||
|
def shift_right(rg, fill_bit = 0):
|
||||||
|
return str(fill_bit) + rg[:-1]
|
||||||
|
|
||||||
|
r = shift_right
|
||||||
|
|
||||||
|
|
||||||
|
def sum_supplementary_codes(x, y, size):
|
||||||
|
return al(bin(int("0b"+x, 2) + int("0b"+y, 2))[2:], size)
|
||||||
|
|
||||||
|
sum = sum_supplementary_codes
|
||||||
|
|
||||||
|
|
||||||
|
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:]
|
||||||
|
if len(result) > size:
|
||||||
|
return al(result, size), '1'
|
||||||
|
else:
|
||||||
|
return al(result, size), '0'
|
||||||
|
|
||||||
|
sump = sum_supplementary_codes_with_overflow
|
||||||
|
|
||||||
|
|
||||||
|
def invert_bit(b):
|
||||||
|
if b == '0':
|
||||||
|
return '1'
|
||||||
|
elif b == '1':
|
||||||
|
return '0'
|
||||||
|
else:
|
||||||
|
print(f"binutils: detected impossible call: inv({b})")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
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
|
||||||
139
src/divide.py
Normal file
139
src/divide.py
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
import bitutils as bu
|
||||||
|
|
||||||
|
def divide(n, int_x, int_y, method):
|
||||||
|
if method == 1:
|
||||||
|
# getting binary values
|
||||||
|
x = bu.ar(bin(int_x)[2:], n)
|
||||||
|
y = bu.ar(bin(int_y)[2:], n)
|
||||||
|
|
||||||
|
# getting the supplementary code of X
|
||||||
|
y_inv = "".join([bu.inv(i) for i in y]) # invert
|
||||||
|
y_inv = bu.sum(y_inv, '1', n) # +1
|
||||||
|
|
||||||
|
# writing startup register values
|
||||||
|
# registers order: RG3, RG2, RG1
|
||||||
|
rg_table = [[['start', '1'*(n-1), x, y, '-'], ['start', '1'*(n-1), x, y_inv, '-']]]
|
||||||
|
|
||||||
|
# iterations counter
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
while rg_table[-1][-1][1][0] != '0':
|
||||||
|
i += 1
|
||||||
|
rg_table.append([])
|
||||||
|
|
||||||
|
if rg_table[-2][-1][2][0] == '1':
|
||||||
|
rg_table[-1].append([
|
||||||
|
i,
|
||||||
|
rg_table[-2][-1][1], # copy previous value
|
||||||
|
bu.sum(rg_table[-2][-1][2], rg_table[0][0][3], n), # RG2 := RG2 + RG1
|
||||||
|
'-',
|
||||||
|
"RG2 := RG2 + RG1"
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
rg_table[-1].append([
|
||||||
|
i,
|
||||||
|
rg_table[-2][-1][1], # copy previous value
|
||||||
|
bu.sum(rg_table[-2][-1][2], rg_table[0][1][3], n), # RG2 := RG2 - RG1
|
||||||
|
'-',
|
||||||
|
"RG2 := RG2 - RG1"
|
||||||
|
])
|
||||||
|
|
||||||
|
rg_table[-1].append([
|
||||||
|
i,
|
||||||
|
bu.l(rg_table[-1][-1][1], bu.inv(rg_table[-1][-1][2][0])),
|
||||||
|
bu.l(rg_table[-1][-1][2], '0'),
|
||||||
|
'-',
|
||||||
|
"l(RG3).RG2[n+2], l(RG2).0"
|
||||||
|
])
|
||||||
|
|
||||||
|
return rg_table, rg_table[-1][-1][1][1:]
|
||||||
|
|
||||||
|
elif method == 2:
|
||||||
|
# getting binary values
|
||||||
|
x = '0' + bu.al(bin(int_x)[2:], 2*n)
|
||||||
|
y = '0' + bu.al(bin(int_y)[2:], 2*n)
|
||||||
|
|
||||||
|
# writing startup register values
|
||||||
|
# registers order: RG3, RG2, RG1
|
||||||
|
rg_table = [[['start', '1'*(n+1), x, y, '-']]]
|
||||||
|
|
||||||
|
# iterations counter
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
while rg_table[-1][-1][1][0] != '0':
|
||||||
|
i += 1
|
||||||
|
rg_table.append([])
|
||||||
|
|
||||||
|
if rg_table[-2][-1][2][0] == '1':
|
||||||
|
new_rg2, p = bu.sump(rg_table[-2][-1][2], rg_table[-2][0][3], 2*n+1)
|
||||||
|
rg_table[-1].append([
|
||||||
|
i,
|
||||||
|
bu.l(rg_table[-2][-1][1], p), # l(RG3).SM(p)
|
||||||
|
new_rg2, # RG2 := RG2 + RG1
|
||||||
|
bu.r(rg_table[-2][0][3], '0'),
|
||||||
|
"RG2 := RG2 + RG1\n" \
|
||||||
|
"RG1 := 0.r(RG1)\n" \
|
||||||
|
"RG3 := l(RG3).SM(p)"
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
y_sup = ''
|
||||||
|
invert = False
|
||||||
|
for r in rg_table[-2][0][3][::-1]:
|
||||||
|
if invert:
|
||||||
|
y_sup += bu.inv(r)
|
||||||
|
else:
|
||||||
|
y_sup += r
|
||||||
|
|
||||||
|
if r == '1':
|
||||||
|
invert = True
|
||||||
|
|
||||||
|
y_sup = y_sup[::-1]
|
||||||
|
|
||||||
|
new_rg2, p = bu.sump(rg_table[-2][-1][2], y_sup, 2*n+1)
|
||||||
|
|
||||||
|
rg_table[-1].append([
|
||||||
|
i,
|
||||||
|
bu.l(rg_table[-2][-1][1], p), # copy previous value
|
||||||
|
new_rg2, # RG2 := RG2 - RG1
|
||||||
|
bu.r(rg_table[-2][0][3], '0'),
|
||||||
|
"RG2 := RG2 - !RG1 + D\n" \
|
||||||
|
"RG1 := 0.r(RG1)\n" \
|
||||||
|
"RG3 := l(RG3).SM(p)"
|
||||||
|
])
|
||||||
|
|
||||||
|
return rg_table, rg_table[-1][-1][1][1:]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 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, result = divide(n, x, y, method)
|
||||||
|
|
||||||
|
from lib.prettytable import PrettyTable
|
||||||
|
pt = PrettyTable()
|
||||||
|
pt.field_names = ["Iteration", "RG3", "RG2", "RG1", "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])
|
||||||
|
|
||||||
|
print(pt)
|
||||||
|
print(f"Result: {result}")
|
||||||
@@ -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.")
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -86,7 +148,8 @@ if __name__ == "__main__":
|
|||||||
method = int(input("Method: "))
|
method = int(input("Method: "))
|
||||||
|
|
||||||
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
1
src/www/bitutils.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../bitutils.py
|
||||||
1
src/www/divide.py
Symbolic link
1
src/www/divide.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../divide.py
|
||||||
1
src/www/lib
Symbolic link
1
src/www/lib
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../lib/
|
||||||
1
src/www/multiply.py
Symbolic link
1
src/www/multiply.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../multiply.py
|
||||||
23
src/www/web-divide.py
Normal file
23
src/www/web-divide.py
Normal 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
23
src/www/web-multiply.py
Normal 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!")
|
||||||
Reference in New Issue
Block a user