Home > Software engineering >  How to multiply two real numbers of any base in Python?
How to multiply two real numbers of any base in Python?

Time:09-27

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 ints, 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 0s and removing trailing ..

The function to_base is from here: https://stackoverflow.com/a/53675480/3052438

  • Related