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
CodePudding user response:
base = 2
s1, s2 = '101.1', '101.1'
d1 = ('.' in s1 and len(s1) - s1.index('.') - 1) or 0
d2 = ('.' in s2 and len(s2) - s2.index('.') - 1) or 0
a, b = int(s1.replace('.', ''), base), int(s2.replace('.', ''), base)
scale = base**(d1 d2)
intpart, fracpart = (a*b) // scale, (a*b) % scale
res = '%s.%s' % (baseN(intpart, base), baseN(fracpart, base).rjust(d1 d2, '0'))
res # '11110.01'
Probably some edge cases with the formatting left to do. The principle is 101.1 * 101.1 = (1011 * 2^-1) * (1011 * 2^-1) = 1011*1011 * 2^(-1 -1) = 1111001 * 2^-2 = 11110.01
CodePudding user response:
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