I would like to write a function that accepts two numbers and their base (aka radix) and multiplies them.
base = int(input())
num1 = input()
num2 = input()
def multiply(num1: str, num2: str, base: int) -> str:
pass
I tried to convert them to decimal and then multiply them but the precision can be lost.
For example:
2
101.1
101.1
is
11110.01
The code saves positions of the .
s (if they are present) and removes them.
Strings are then converted to int
s, multiplied and the result is converted back to string at which point a .
is inserted at the appropriate position if necessary.
#!/usr/bin/env python
base = 2
num1 = '101.1'
num2 = '101.1'
def parsenum(num: str, base: int) -> (int, int):
shift = len(num) - num.index('.') - 1 if '.' in num else 0
num = num.replace('.', '')
return int(num, base), shift
BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(s, b):
res = ""
while s:
res+=BS[s%b]
s//= b
return res[::-1] or "0"
def num2str(num: int, shift: int, base: int) -> str:
string = to_base(abs(num), base)
if shift:
if len(string) <= shift:
string = '0' * (shift - len(string) + 1) + string
pos = len(string) - shift
string = string[:pos] + '.' + string[pos:]
string = string.rstrip('0').rstrip('.')
if num < 0:
string = '-' + string
return string
def multiply(num1: str, num2: str, base: int) -> str:
num1, shift1 = parsenum(num1, base)
num2, shift2 = parsenum(num2, base)
result_num, result_shift = num1 * num2, shift1 + shift2
return num2str(result_num, result_shift, base)
print(multiply(num1, num2, base))
I'm 95% sure I've got all the corner cases, including handling negative numbers, stripping unnecessary 0
s and removing trailing .
.
The function to_base
is from here: https://stackoverflow.com/a/53675480/3052438