Search code examples
pythonmathmultiplication

How to multiply two real numbers of any base in Python?


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

Solution

  • 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