[面试][算法]任意进制整数/小数间的转换

原理比较简单,参考注释即可理解,仅作笔记用于速查。

整数部分

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进制完成任意进制间的转换
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值