欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python 进制转换, 实现任意进制转换为任意进制的方法, 支持小数和负数, 二进制转十进制, 十进制转二进制, 小数进制转换, k进制转换

程序员文章站 2022-07-15 09:56:41
...

代码如下:

# -*- coding = utf-8 -*-
# @Time : 2021/1/23 16:10
# @Author : Suage
# @File : SysConvert.py

from threading import Lock


class StringBuilder:
    def __init__(self, content=None, convert_way='STR', convert_function=None):
        if content is None:
            self.content = list()
        elif isinstance(content, str):
            self.content = list(content)
        else:
            if convert_way.lower() == 'str':
                self.content = list(str(content))
            elif convert_way.lower() == 'repr':
                self.content = list(repr(content))
            else:
                self.content = list(convert_function(content))

    def get_str(self):
        """
        以字符串形式输出内容

        :return: 内容
        """
        return ''.join(self.content)

    def append(self, text, location=-1):
        if location == -1:
            self.content.extend(text)
        else:
            for c in text: self.content.insert(location, c)

    def reverse(self):
        self.content.reverse()


class SysConvert:
    __unit: str = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_'

    def __init__(self):
        self.__lock = Lock()
        self.__input_number: str
        self.__sys_in: int
        self.__sys_out: int

    def set_unit(self, unit):
        """
        设置计数用字符

        :param unit: 计数用字符序列
        """
        self.__unit = unit

    def num_split(self):
        """
        拆解数字的整数部分和小数部分
        :return: 整数部分, 小数部分
        """
        return self.__input_number.split('.')

    def __is_int(self):
        """
        判断输入数字是否为整数
        :return: 整数返回True, 小时返回False
        """
        if '.' in self.__input_number: return False
        return True

    def __concert(self, input_num, input_sys, output_sys):
        """
        执行转换
        :return:转换结果
        """
        self.__input_number: str = input_num.upper().replace(' ', '')
        if self.__input_number[0] == '-':
            self.sign = False
            self.__input_number = self.__input_number[1:]
        else:
            self.sign = True
        self.__sys_in: int = input_sys
        self.__sys_out: int = output_sys
        is_int = self.__is_int()
        if is_int:
            if self.input_error(self.__input_number):
                return 'input error'
            return self.__int_concert(self.__input_number)

        int_part, float_part = self.num_split()

        if self.input_error(int_part) or self.input_error(float_part):
            return 'input error'

        number_part = f'{self.__int_concert(int_part)}.{self.__float_concert(float_part)}'
        if self.sign:
            return number_part
        return f'-{number_part}'

    def concert(self, input_num, input_sys, output_sys):
        """
        执行转换

        :param input_num: 输入数字
        :param input_sys: 输入数字进制
        :param output_sys: 输出数字进制
        :return: 转换结果
        """
        self.__lock.acquire()
        try:
            res = self.__concert(input_num, input_sys, output_sys)
        finally:
            self.__lock.release()
        return res

    def __int_concert(self, int_part):
        """
        整数部分转换为目标进制

        :param int_part: 要转换的数字
        :return: 转换结果
        """
        number = self.__any_sys_to_int(int_part)
        return self.__int_to_any_sys(number)

    def __any_sys_to_int(self, number):
        """
        将任何进制的整数部分转换为计算机可运算的整数类型

        :param number: 要转换的整数部分
        :return: 转换结果
        """
        res = 0
        number = number[::-1]
        for i in range(len(number)):
            res += self.__unit.index(number[i]) * pow(self.__sys_in, i)
        return res

    def __int_to_any_sys(self, num):
        """
        将整数类型的数字装换为目标进制的数字
        :param num: 要转换的数字
        :return: 转换结果
        """
        _sb: StringBuilder = StringBuilder()
        while True:
            num, y = divmod(num, self.__sys_out)
            _sb.append(self.__unit[y])
            if num < self.__sys_out:
                _sb.append(self.__unit[num])
                break
        _sb.reverse()
        return _sb.get_str().lstrip("0")

    def __float_concert(self, float_part):
        """
        小数部分转换为目标进制

        :param float_part: 要转换的小数部分(小数点后的部分)
        :return: 转换结果(小数点后面部分)
        """
        number = self.__any_sys_to_float(float_part)
        return self.__float_to_any_sys(number)

    def __any_sys_to_float(self, number):
        """
        将任何进制的整数部分转换为计算机可运算的整数类型

        :param number: 要转换的整数部分
        :return: 转换结果
        """
        res = 0
        number = number
        for i in range(len(number)):
            res += self.__unit.index(number[i]) * pow(1 / self.__sys_in, (i + 1))
        return res

    def __float_to_any_sys(self, num):
        """
        将整数类型的数字装换为目标进制的数字
        :param num: 要转换的数字
        :return: 转换结果
        """
        _sb: StringBuilder = StringBuilder()
        n = num
        for _ in range(15):
            n = n * self.__sys_out
            n_int = int(n)
            n = n - n_int
            _sb.append(self.__unit[n_int])
            if n == 0: break
        return _sb.get_str()

    def input_error(self, num):
        for c in num:
            if self.__unit.index(c) >= self.__sys_in: return True
        return False


if __name__ == '__main__':
    c1 = SysConvert()
    res1 = c1.concert(input_num='BYSUAGE.I', input_sys=36, output_sys=6)
    res2 = c1.concert(input_num=res1, input_sys=6, output_sys=36)
    print(res1, res2, sep='\n')

运行结果:
15544450142422.3
BYSUAGE.I

写了将近6个小时才写完, 好累…