Python 進位制轉換, 實現任意進位制轉換為任意進位制的方法, 支援小數和負數, 二進位制轉十進位制, 十進位制轉二進位制, 小數進位制轉換, k進位制轉換
阿新 • • 發佈:2021-01-25
程式碼如下:
# -*- 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個小時才寫完, 好累…