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

9 篇文章 0 订阅
8 篇文章 0 订阅

代码如下:

# -*- 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个小时才写完, 好累…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值