如何将任意进制的字符串转换为十进制?

3

我想将一个十进制数转换为任意进制,然后再把它转回十进制。我在另一个问题中找到了下面的代码:

def int2base(x,b,alphabet='0123456789abcdefghijklmnopqrstuvwxyz'):
    'convert an integer to its string representation in a given base'
    if b<2 or b>len(alphabet):
        if b==64: # assume base64 rather than raise error
            alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        else:
            raise AssertionError("int2base base out of range")
    if isinstance(x,complex): # return a tuple
        return ( int2base(x.real,b,alphabet) , int2base(x.imag,b,alphabet) )
    if x<=0:
        if x==0:
            return alphabet[0]
        else:
            return  '-' + int2base(-x,b,alphabet)
    # else x is non-negative real
    rets=''
    while x>0:
        x,idx = divmod(x,b)
        rets = alphabet[idx] + rets
    return rets

当我将十进制转换为十六进制时:
in_base16 = int2base(number, 16)

这个功能可行,但当我尝试将结果转换回十进制(即基数为10)时:

back_to_10 = int2base(in_base16, 10)

当我尝试运行它时,它会报错:

    if x<=0:
    TypeError: '<=' not supported between instances of 'str' and 'int'

由于某些原因,它无法将字符串转换回数字。我不明白为什么。如何将任意进制的数字转换回十进制?


"0x10" <= 0 is something python does not understand... try int(in_base16,16) - Joran Beasley
你正在使用的函数将一个整数转换为另一种进制下的字符串表示。通过将其输出传递给自身,你现在正在将一个字符串传递给一个只接受整数的函数。在将其放入你所拥有的函数之前,你需要使用内置的 int(string, base) 函数将你的数字转换为整数。 - Random Davis
@RandomDavis 哦,我现在明白了。但是有没有一种简单的方法将该数字表示转换回十进制? - Un1
是的,它是Python内置的:int(string, base)。你只需要将第二个函数调用更改为back_to_10 = int2base(int(in_base16, 16), 10)。如果这确实是你所需要的,我已经将这个评论转换成了答案。 - Random Davis
4个回答

1

您需要一个函数来将整数转换为基数(返回表示该基数中数字的字符串 - 这里是最高36进制):

digits = '0123456789abcdefghijklmnopqrstuvwxyz'

def int2base(n, b=2, digits=digits):
    "convert integer n to base b"
    if n < 0:
        raise ValueError("no negative numbers")
    if n < b:
        return digits[n]
    res = []
    q = n
    while q:
        q, r = divmod(q, b)
        res.append(digits[r])
    return ''.join(reversed(res))

还有一个将基数转换回整数的函数:

def base2int(s, base=2, digits=digits):
    "convert string s representing a number in base to int (base 10)"
    if not (2 <= base <= len(digits)):
        raise ValueError("base must be >= 2 and <= %d" % len(digits))
    res = 0
    for i, v in enumerate(reversed(s)):
        digit = digits.index(v)
        res += digit * (base ** i)
    return res

1
你的基本问题在于签名:你的函数只能处理整数类型的 x。相反,你需要一个第二个处理字符串的函数或者在这个程序的顶部进行类型检查以检测输入类型。
基本问题在于你假设可以通过简单的引用获取基数(底数)内数字的值;这对于整数是有效的,但不适用于字符串。 "9" 不会产生数值为 9 的数字值;"B" 不会给你 11。
相反,你需要将字符传递给 index 函数并获取返回值。
digit_value = alphabet.index(char)

这将为您提供字符在字母表中的位置,这是您计算所需的数字值。

你能继续吗?


是的,我现在明白了。其他回答都很好用,但内置函数在进制超过36时就无法使用了。我现在会尝试你的方法。谢谢。 - Un1
我尝试在stackoverflow(通过谷歌)上找到解决方案,但我找不到将其转换回十进制的方法。目前我还无法自己完成它。尝试在函数中添加你的代码行时,我已经出现了2个错误,唉,新手程序员... - Un1
一位年迈程序员的建议:在尝试让一个函数完成两个任务之前,先编写一个单独的函数。 - Prune
首先,让它工作;其次,让它工作得好;最后,让它看起来漂亮。 - Prune
谢谢你的建议。我把你的代码作为一个独立的函数运行了,它可以显示字母在字母表中的索引。现在我只需要把它放在一个for循环中,就可以用数字替换所有的字母了,对吧?而且它也适用于任何进制,是吗? - Un1
显示剩余4条评论

1
您的int2base函数只接受整数作为输入,因此您需要将字符串转换为整数。因此,您可以简单地使用内置函数int(string, base)来完成这个操作:
in_base16 = int2base(number, 16)
back_to_10 = int2base(int(in_base16, 16), 10)

这个很好用。


谢谢。确实起作用了。但似乎只适用于范围为2-36的情况,int()base必须>= 2且<= 36 - Un1
听起来如果你需要更多的进制,你只需要重新设计你的int2base函数以实现另一个方向的转换。 - Random Davis

1
如果 base-n 不超过 36,您可以使用 内置函数 int(str,base)
>>> int('AA', 32)
330

1
我知道那个,但还是谢谢你。这是一个不错的选择。 - Un1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接