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