原理比较简单,参考注释即可理解,仅作笔记用于速查。
整数部分
1. 10进制转为n进制
不断对n取余作为该位上的n进制值即可。
def ten2n_int(num: int, n: int) -> str: # 10进制转为n进制
if num == 0:
return "0"
res = ""
pos = num > 0 # 是否为正数
num = abs(num)
while num > 0:
num, r = divmod(num, n) # Aka: num //= n; r = num % r;
res += chr(r - 10 + 97) if r >= 10 else chr(r + 48)
return ("" if pos else "-") + res[::-1]
2. n进制转为10进制
从头往后,不断将当前位的n进制数乘以相应的n进制基数,累计到10进制结果上即可。
def n2ten_int(num: str, n: int) -> int: # n进制转为10进制,默认进制不超过36(即'z'+10)
if num == "":
return 0
num.lower() # 默认都采用小写表示
res, pos = 0, bool(num[0] != '-')
if not pos: # 如果是负数,删去开头的 '-' 字符
num = num[1:]
base = n ** len(num)
for i in range(len(num)):
base //= n # ord('a') = 97, ord('0') = 48 | base 是当前的基数
res += ((ord(num[i]) - 97 + 10) if num[i].isalpha() else (ord(num[i]) - 48)) * base
return res * (1 if pos else -1)
3. n进制转为m进制
直接使用取巧的方式,进制通过n->10->m进行变换即可,否则需要编写基于m进制的加法。
def n2m_int(num: str, n: int, m: int) -> str: # n进制转为m进制
return ten2n_int(n2ten_int(num, n), m) # 借助10进制完成任意进制间的转换
小数部分
1. 10进制小数转为n进制小数
不断乘进制数,取整数位作为当前位的值,直至小数部分为0。
def ten2n_float(num: float, n: int, max_len: int = 5) -> str:
assert 0 < abs(num) < 1 #
res, pos = "0.", num > 0
num = abs(num)
while num > 0 and len(res) - 2 <= max_len:
num *= n
num, c = math.modf(num)
c = int(c)
res += chr(c - 10 + 97) if c >= 10 else chr(c + 48)
return ("" if pos else "-") + res
2. n进制小数转为10进制小数
跟jn进制整数转10进制整数一样的套路。
def n2ten_float(num: str, n: int) -> int: # num like "0.xxx"
res, pos = 0, num[0] != '-'
num = num[2:] if pos else num[3:]
base = 1.0
for i in range(len(num)):
base /= n
res += ((ord(num[i]) - 97 + 10) if num[i].isalpha() else (ord(num[i]) - 48)) * base
return res * (1 if pos else -1)
3. n进制小数转m进制小数
def n2m_float(num: str, n: int, m: int) -> str: # n进制转为m进制小数
return ten2n_float(n2ten_float(num, n), m) # 借助10进制完成任意进制间的转换