原理比较简单,参考注释即可理解,仅作笔记用于速查。
不断对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]从头往后,不断将当前位的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)直接使用取巧的方式,进制通过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进制完成任意进制间的转换不断乘进制数,取整数位作为当前位的值,直至小数部分为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跟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)