269

Python允许通过给定基数的字符串轻松创建整数

int(str, base). 

我想执行相反的操作:从整数创建字符串,即我想要一些函数int2base(num, base),例如:

int(int2base(x, b), b) == x

函数名/参数顺序并不重要。

对于任何可以接受的数字和基数xbint()

这是一个易于编写的函数:实际上它比在这个问题中描述它更容易。但是,我觉得我一定错过了什么。

我知道函数bin, oct, hex,但由于以下几个原因我不能使用它们:

  • 这些功能在旧版本的 Python 上不可用,我需要与 (2.2) 兼容

  • 我想要一个通用的解决方案,可以针对不同的基础以相同的方式调用

  • 我想允许 2、8、16 以外的碱基

有关的

4

33 回答 33

161

令人惊讶的是,人们只给出了转换为小碱基(小于英文字母的长度)的解决方案。没有尝试给出将任意基数从 2 转换为无穷大的解决方案。

所以这是一个超级简单的解决方案:

def numberToBase(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]

因此,如果您需要将一些超大数字转换为基数577

numberToBase(67854 ** 15 - 102, 577), 会给你一个正确的解决方案: [4, 473, 131, 96, 431, 285, 524, 486, 28, 23, 16, 82, 292, 538, 149, 25, 41, 483, 100, 517, 131, 28, 0, 435, 197, 264, 455],

您可以稍后将其转换为您想要的任何基础

  1. 在某些时候你会注意到有时没有内置的库函数来做你想做的事情,所以你需要自己编写。如果您不同意,请发布您自己的带有内置函数的解决方案,该函数可以将基数为 10 的数字转换为基数 577。
  2. 这是由于缺乏理解某些基础中的数字的含义。
  3. 我鼓励你想一想为什么你的方法中的 base 只适用于 n <= 36。一旦你完成了,很明显为什么我的函数返回一个列表并具有它的签名。
于 2015-02-23T02:48:46.873 回答
112

如果您需要与 Python 的古老版本兼容,您可以使用gmpy(它确实包含一个快速、完全通用的 int 到字符串转换功能,并且可以为此类古老版本构建 - 您可能需要尝试较旧的版本,因为最近的版本还没有针对古老的 Python 和 GMP 版本进行测试,只有最近的版本),或者,为了降低速度但更方便,使用 Python 代码——例如,对于 Python 2,最简单的是:

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[int(x % base)])
        x = int(x / base)

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)

对于 Python 3,int(x / base)会导致不正确的结果,必须更改为x // base

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[x % base])
        x = x // base

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)
于 2010-02-15T16:44:10.387 回答
110
"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144
于 2010-09-05T19:23:40.340 回答
97
def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

参考: http ://code.activestate.com/recipes/65212/

请注意,这可能会导致

RuntimeError: maximum recursion depth exceeded in cmp

对于非常大的整数。

于 2010-02-15T16:41:46.863 回答
40
>>> numpy.base_repr(10, base=3)
'101'

请注意,numpy.base_repr()它的基数限制为 36。否则它会抛出一个ValueError

于 2019-06-03T16:46:05.040 回答
24

递归的

我会简化投票最多的答案

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n, b): 
    return "0" if not n else to_base(n//b, b).lstrip("0") + BS[n%b]

对于RuntimeError: maximum recursion depth exceeded in cmp非常大的整数和负数具有相同的建议。(你可以使用sys.setrecursionlimit(new_limit)

迭代

避免递归问题

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(s, b):
    res = ""
    while s:
        res+=BS[s%b]
        s//= b
    return res[::-1] or "0"
于 2018-12-07T19:05:51.597 回答
21

很好的答案!我想我的问题的答案是“不”我没有错过一些明显的解决方案。这是我将使用的函数,它浓缩了答案中表达的好主意。

  • 允许调用者提供的字符映射(允许 base64 编码)
  • 检查负数和零
  • 将复数映射为字符串元组


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

于 2010-02-15T17:28:27.040 回答
14

您可以baseconv.py从我的项目中使用:https ://github.com/semente/python-baseconv

示例用法:

>>> from baseconv import BaseConverter
>>> base20 = BaseConverter('0123456789abcdefghij')
>>> base20.encode(1234)
'31e'
>>> base20.decode('31e')
'1234'
>>> base20.encode(-1234)
'-31e'
>>> base20.decode('-31e')
'-1234'
>>> base11 = BaseConverter('0123456789-', sign='$')
>>> base11.encode('$1234')
'$-22'
>>> base11.decode('$-22')
'$1234'

baseconv.base2有一些 bultin 转换器,例如baseconv.base16baseconv.base64

于 2012-09-25T20:42:40.047 回答
4
def base(decimal ,base) :
    list = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    other_base = ""
    while decimal != 0 :
        other_base = list[decimal % base] + other_base
        decimal    = decimal / base
    if other_base == "":
        other_base = "0"
    return other_base

print base(31 ,16)

输出:

“1F”

于 2014-10-04T01:53:01.790 回答
2

http://code.activestate.com/recipes/65212/

def base10toN(num,n):
    """Change a  to a base-n number.
    Up to base-36 is supported without special notation."""
    num_rep={10:'a',
         11:'b',
         12:'c',
         13:'d',
         14:'e',
         15:'f',
         16:'g',
         17:'h',
         18:'i',
         19:'j',
         20:'k',
         21:'l',
         22:'m',
         23:'n',
         24:'o',
         25:'p',
         26:'q',
         27:'r',
         28:'s',
         29:'t',
         30:'u',
         31:'v',
         32:'w',
         33:'x',
         34:'y',
         35:'z'}
    new_num_string=''
    current=num
    while current!=0:
        remainder=current%n
        if 36>remainder>9:
            remainder_string=num_rep[remainder]
        elif remainder>=36:
            remainder_string='('+str(remainder)+')'
        else:
            remainder_string=str(remainder)
        new_num_string=remainder_string+new_num_string
        current=current/n
    return new_num_string

这是来自同一链接的另一个

def baseconvert(n, base):
    """convert positive decimal integer n to equivalent in another base (2-36)"""

    digits = "0123456789abcdefghijklmnopqrstuvwxyz"

    try:
        n = int(n)
        base = int(base)
    except:
        return ""

    if n < 0 or base < 2 or base > 36:
        return ""

    s = ""
    while 1:
        r = n % base
        s = digits[r] + s
        n = n / base
        if n == 0:
            break

    return s
于 2010-02-15T16:40:00.210 回答
2

我为此做了一个 pip 包。

我建议你使用我的 bases.py https://github.com/kamijotouma/bases.py,它的灵感来自 bases.js

from bases import Bases
bases = Bases()

bases.toBase16(200)                // => 'c8'
bases.toBase(200, 16)              // => 'c8'
bases.toBase62(99999)              // => 'q0T'
bases.toBase(200, 62)              // => 'q0T'
bases.toAlphabet(300, 'aAbBcC')    // => 'Abba'

bases.fromBase16('c8')               // => 200
bases.fromBase('c8', 16)             // => 200
bases.fromBase62('q0T')              // => 99999
bases.fromBase('q0T', 62)            // => 99999
bases.fromAlphabet('Abba', 'aAbBcC') // => 300

请参阅https://github.com/kamijotouma/bases.py#known-basesalphabets 了解可用的碱基

编辑:点链接https://pypi.python.org/pypi/bases.py/0.2.2

于 2015-05-27T10:21:54.407 回答
0
>>> import string
>>> def int2base(integer, base):
        if not integer: return '0'
        sign = 1 if integer > 0 else -1
        alphanum = string.digits + string.ascii_lowercase
        nums = alphanum[:base]
        res = ''
        integer *= sign
        while integer:
                integer, mod = divmod(integer, base)
                res += nums[mod]
        return ('' if sign == 1 else '-') + res[::-1]


>>> int2base(-15645, 23)
'-16d5'
>>> int2base(213, 21)
'a3'
于 2010-02-15T16:45:34.283 回答
0

为感兴趣的人提供递归解决方案。当然,这不适用于负二进制值。您需要实现二的补码。

def generateBase36Alphabet():
    return ''.join([str(i) for i in range(10)]+[chr(i+65) for i in range(26)])

def generateAlphabet(base):
    return generateBase36Alphabet()[:base]

def intToStr(n, base, alphabet):
    def toStr(n, base, alphabet):
        return alphabet[n] if n < base else toStr(n//base,base,alphabet) + alphabet[n%base]
    return ('-' if n < 0 else '') + toStr(abs(n), base, alphabet)

print('{} -> {}'.format(-31, intToStr(-31, 16, generateAlphabet(16)))) # -31 -> -1F
于 2015-01-27T13:05:30.790 回答
0
def int2base(a, base, numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    baseit = lambda a=a, b=base: (not a) and numerals[0]  or baseit(a-a%b,b*base)+numerals[a%b%(base-1) or (a%b) and (base-1)]
    return baseit()

解释

在任何基础中,每个数字都等于 a1+a2*base**2+a3*base**3...“任务”是找到所有 a 。

对于每N=1,2,3...一个代码都 aN*base**N通过 b “模数”来隔离 a ,b=base**(N+1) 其中切片所有 a 大于 N ,并通过每次调用 func 时减少 a 来切片所有序列小于 N 的 a aN*base**N

Base%(base-1)==1 因此 base**p%(base-1)==1 因此 q*base^p%(base-1)==q 只有一个例外当 q=base-1它返回 0。为了解决这个问题,如果它返回 0,则 func 正在检查它是否从一开始就为 0。


好处

在这个示例中,只有一个乘法(而不是除法)和一些相对花费少量时间的 moudulueses。

于 2016-04-24T12:07:24.643 回答
0
def base_changer(number,base):
    buff=97+abs(base-10)
    dic={};buff2='';buff3=10
    for i in range(97,buff+1):
        dic[buff3]=chr(i)
        buff3+=1   
    while(number>=base):
        mod=int(number%base)
        number=int(number//base)
        if (mod) in dic.keys():
            buff2+=dic[mod]
            continue
        buff2+=str(mod)
    if (number) in dic.keys():
        buff2+=dic[number]
    else:
        buff2+=str(number)

    return buff2[::-1]   
于 2019-09-08T17:43:50.650 回答
0

这是一个如何将任意碱基的数量转换为另一个碱基的示例。

from collections import namedtuple

Test = namedtuple("Test", ["n", "from_base", "to_base", "expected"])


def convert(n: int, from_base: int, to_base: int) -> int:
    digits = []
    while n:
        (n, r) = divmod(n, to_base)
        digits.append(r)    
    return sum(from_base ** i * v for i, v in enumerate(digits))


if __name__ == "__main__":
    tests = [
        Test(32, 16, 10, 50),
        Test(32, 20, 10, 62),
        Test(1010, 2, 10, 10),
        Test(8, 10, 8, 10),
        Test(150, 100, 1000, 150),
        Test(1500, 100, 10, 1050000),
    ]

    for test in tests:
        result = convert(*test[:-1])
        assert result == test.expected, f"{test=}, {result=}"
    print("PASSED!!!")
于 2020-02-01T10:36:41.517 回答
0
def base_conversion(num, base):
    digits = []
    while num > 0:
        num, remainder = divmod(num, base)
        digits.append(remainder)
    return digits[::-1]
于 2020-02-04T20:46:47.110 回答
0

假设我们要将 14 转换为基数 2。我们重复应用除法算法,直到商为 0:

14 = 2 x 7

7 = 2 x 3 + 1

3 = 2 x 1 + 1

1 = 2 x 0 + 1

二进制表示只是从下到上读取的余数。这可以通过展开来证明

14 = 2 x 7 = 2 x (2 x 3 + 1) = 2 x (2 x (2 x 1 + 1) + 1) = 2 x (2 x (2 x (2 x 0 + 1) + 1) + 1) = 2^3 + 2^2 + 2

代码是上述算法的实现。

def toBaseX(n, X):
strbin = ""
while n != 0:
    strbin += str(n % X)
    n = n // X
return strbin[::-1]
于 2021-06-24T10:42:03.360 回答
0

这是我的方法。首先将数字转换为字符串。

    def to_base(n, base):
        if base == 10:
            return n
        
        result = 0
        counter = 0
        
        while n:
            r = n % base
            n //= base
            result += r * 10**counter
            counter+=1
        return str(result)
于 2021-07-10T04:52:52.373 回答
0

我已经编写了这个函数,用于在不同的基础上进行编码。我还提供了将结果偏移值“偏移量”的方法。如果您想编码到 64 以上的基数,但保留可显示的字符(如基数 95),这很有用。

我还尝试避免反转输出“列表”并尝试最小化计算操作。pow(base) 数组根据需要计算并保留以供对该函数的其他调用。

输出是一个二进制字符串

pows = {}

######################################################
def encode_base(value,
                base = 10,
                offset = 0) :

    """
    Encode value into a binary string, according to the desired base.

    Input :
        value : Any positive integer value
        offset : Shift the encoding (eg : Starting at chr(32))
        base : The base in which we'd like to encode the value

    Return : Binary string

    Example : with : offset = 32, base = 64

              100 -> !D
              200 -> #(
    """

    # Determine the number of loops
    try :
        pb = pows[base]

    except KeyError :
        pb = pows[base] = {n : base ** n for n in range(0, 8) if n < 2 ** 48 -1}

    for n in pb :
        if value < pb[n] :
            n -= 1
            break

    out = []
    while n + 1 :
        b = pb[n]
        out.append(chr(offset + value // b))
        n -= 1
        value %= b

    return ''.join(out).encode()
于 2021-08-18T19:25:12.280 回答
0

此函数将任何整数从任何基数转换为任何基数

def baseconvert(number, srcbase, destbase):
    if srcbase != 10:
        sum = 0
        for _ in range(len(str(number))):
            sum += int(str(number)[_]) * pow(srcbase, len(str(number)) - _ - 1)
        b10 = sum
        return baseconvert(b10, 10, destbase)
    end = ''
    q = number
    while(True):
        r = q % destbase
        q = q // destbase
        end = str(r) + end
        if(q<destbase):
            end = str(q) + end
            return int(end)
于 2021-12-27T07:12:51.863 回答
0

下面提供的 Python 代码将 Python 整数转换为任意基数(从 2 到无穷大)的字符串,并且可以双向工作。因此,所有创建的字符串都可以通过为 N 提供字符串而不是整数来转换回 Python 整数。该代码仅适用于有意的正数(在我看来,我不想深入研究负值及其位表示的一些麻烦)。只需从此代码中选择您需要、想要或喜欢的内容,或者只是愉快地了解可用选项。很多只是为了记录所有各种可用的方法(例如,Oneliner 似乎并不快,即使承诺会如此)。

我喜欢 Salvador Dali 提出的无限大基地的格式。一个很好的提议,即使对于简单的二进制位表示也能很好地工作。请注意,对于infiniteBase=True 格式的字符串,width=x 填充参数适用于数字而不是整数。看起来,处理infiniteBase 数字格式的代码比其他选项运行得更快——另一个使用它的原因是什么?

我不喜欢使用 Unicode 来扩展可用于数字的符号数量,所以不要查看下面的代码,因为它不存在。改用建议的infiniteBase 格式或将整数存储为字节以用于压缩目的。

    def inumToStr( N, base=2, width=1, infiniteBase=False,\
    useNumpy=False, useRecursion=False, useOneliner=False, \
    useGmpy=False, verbose=True):
    ''' Positive numbers only, but works in BOTH directions.
    For strings in infiniteBase notation set for bases <= 62 
    infiniteBase=True . Examples of use:
    inumToStr( 17,  2, 1, 1)             # [1,0,0,0,1]
    inumToStr( 17,  3, 5)                #       00122
    inumToStr(245, 16, 4)                #        00F5
    inumToStr(245, 36, 4,0,1)            #        006T
    inumToStr(245245245245,36,10,0,1)    #  0034NWOQBH
    inumToStr(245245245245,62)           #     4JhA3Th 
        245245245245 == int(gmpy2.mpz('4JhA3Th',62))
    inumToStr(245245245245,99,2) # [25,78, 5,23,70,44]
    ----------------------------------------------------
    inumToStr( '[1,0,0,0,1]',2, infiniteBase=True ) # 17 
    inumToStr( '[25,78, 5,23,70,44]', 99) # 245245245245
    inumToStr( '0034NWOQBH', 36 )         # 245245245245 
    inumToStr( '4JhA3Th'   , 62 )         # 245245245245
    ----------------------------------------------------
    --- Timings for N = 2**4096, base=36: 
                                      standard: 0.0023
                                      infinite: 0.0017
                                      numpy   : 0.1277
                                      recursio; 0.0022
                                      oneliner: 0.0146
                For N = 2**8192: 
                                      standard: 0.0075
                                      infinite: 0.0053
                                      numpy   : 0.1369
    max. recursion depth exceeded:    recursio/oneliner
    '''
    show = print
    if type(N) is str and ( infiniteBase is True or base > 62 ):
        lstN = eval(N)
        if verbose: show(' converting a non-standard infiniteBase bits string to Python integer')
        return sum( [ item*base**pow for pow, item in enumerate(lstN[::-1]) ] )
    if type(N) is str and base <= 36:
        if verbose: show('base <= 36. Returning Python int(N, base)')
        return int(N, base)
    if type(N) is str and base <= 62:
        if useGmpy: 
            if verbose: show(' base <= 62, useGmpy=True, returning int(gmpy2.mpz(N,base))')
            return int(gmpy2.mpz(N,base))
        else:
            if verbose: show(' base <= 62, useGmpy=False, self-calculating return value)')
            lstStrOfDigits="0123456789"+ \
                "abcdefghijklmnopqrstuvwxyz".upper() + \
                "abcdefghijklmnopqrstuvwxyz"
            dictCharToPow = {}
            for index, char in enumerate(lstStrOfDigits):
                dictCharToPow.update({char : index}) 
            return sum( dictCharToPow[item]*base**pow for pow, item in enumerate(N[::-1]) )
        #:if
    #:if        
        
    if useOneliner and base <= 36:  
        if verbose: show(' base <= 36, useOneliner=True, running the Oneliner code')
        d="0123456789abcdefghijklmnopqrstuvwxyz"
        baseit = lambda a=N, b=base: (not a) and d[0]  or \
        baseit(a-a%b,b*base)+d[a%b%(base-1) or (a%b) and (base-1)]
        return baseit().rjust(width, d[0])[1:]

    if useRecursion and base <= 36: 
        if verbose: show(' base <= 36, useRecursion=True, running recursion algorythm')
        BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        def to_base(n, b): 
            return "0" if not n else to_base(n//b, b).lstrip("0") + BS[n%b]
        return to_base(N, base).rjust(width,BS[0])
        
    if base > 62 or infiniteBase:
        if verbose: show(' base > 62 or infiniteBase=True, returning a non-standard digits string')
        # Allows arbitrary large base with 'width=...' 
        # applied to each digit (useful also for bits )
        N, digit = divmod(N, base)
        strN = str(digit).rjust(width, ' ')+']'
        while N:
            N, digit = divmod(N, base)
            strN = str(digit).rjust(width, ' ') + ',' + strN
        return '[' + strN
    #:if        
    
    if base == 2:
        if verbose: show(" base = 2, returning Python str(f'{N:0{width}b}')")
        return str(f'{N:0{width}b}')
    if base == 8:
        if verbose: show(" base = 8, returning Python str(f'{N:0{width}o}')")
        return str(f'{N:0{width}o}')
    if base == 16:
        if verbose: show(" base = 16, returning Python str(f'{N:0{width}X}')")
        return str(f'{N:0{width}X}')

    if base <= 36:
        if useNumpy: 
            if verbose: show(" base <= 36, useNumpy=True, returning np.base_repr(N, base)")
            import numpy as np
            strN = np.base_repr(N, base)
            return strN.rjust(width, '0') 
        else:
            if verbose: show(' base <= 36, useNumpy=False, self-calculating return value)')
            lstStrOfDigits="0123456789"+"abcdefghijklmnopqrstuvwxyz".upper()
            strN = lstStrOfDigits[N % base] # rightmost digit
            while N >= base:
                N //= base # consume already converted digit
                strN = lstStrOfDigits[N % base] + strN # add digits to the left
            #:while
            return strN.rjust(width, lstStrOfDigits[0])
        #:if
    #:if
    
    if base <= 62:
        if useGmpy: 
            if verbose: show(" base <= 62, useGmpy=True, returning gmpy2.digits(N, base)")
            import gmpy2
            strN = gmpy2.digits(N, base)
            return strN.rjust(width, '0') 
            # back to Python int from gmpy2.mpz with 
            #     int(gmpy2.mpz('4JhA3Th',62))
        else:
            if verbose: show(' base <= 62, useGmpy=False, self-calculating return value)')
            lstStrOfDigits= "0123456789" + \
                "abcdefghijklmnopqrstuvwxyz".upper() + \
                "abcdefghijklmnopqrstuvwxyz"
            strN = lstStrOfDigits[N % base] # rightmost digit
            while N >= base:
                N //= base # consume already converted digit
                strN = lstStrOfDigits[N % base] + strN # add digits to the left
            #:while
            return strN.rjust(width, lstStrOfDigits[0])
        #:if
    #:if    
#:def
于 2022-02-08T01:17:54.927 回答
0

对于 2 到 9 之间的碱基:

  def to_base(N, base=2):
    N_in_base = ''
    while True:
        N_in_base = str(N % base) + N_in_base
        N //= base
        if N == 0:
            break
    return N_in_base
于 2022-03-04T18:06:20.220 回答
-1
def dec_to_radix(input, to_radix=2, power=None):
    if not isinstance(input, int):
        raise TypeError('Not an integer!')
    elif power is None:
        power = 1

    if input == 0:
        return 0
    else:
        remainder = input % to_radix**power
        digit = str(int(remainder/to_radix**(power-1)))
        return int(str(dec_to_radix(input-remainder, to_radix, power+1)) + digit)

def radix_to_dec(input, from_radix):
    if not isinstance(input, int):
        raise TypeError('Not an integer!')
    return sum(int(digit)*(from_radix**power) for power, digit in enumerate(str(input)[::-1]))

def radix_to_radix(input, from_radix=10, to_radix=2, power=None):
    dec = radix_to_dec(input, from_radix)
    return dec_to_radix(dec, to_radix, power)
于 2015-08-10T22:01:40.607 回答
-1
def baseConverter(x, b):
    s = ""
    d = string.printable.upper()
    while x > 0:
        s += d[x%b]
        x = x / b
    return s[::-1]
于 2016-01-23T20:41:17.307 回答
-1

另一个简短的(更容易理解 imo):

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    return (int_to_str(n/b, b, symbols) if n >= b else "") + symbols[n%b]

并通过适当的异常处理:

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    try:
        return (int_to_str(n/b, b) if n >= b else "") + symbols[n%b]
    except IndexError:
        raise ValueError(
            "The symbols provided are not enough to represent this number in "
            "this base")
于 2016-01-26T14:05:44.490 回答
-1

这是一个处理有符号整数和自定义数字的递归版本。

import string

def base_convert(x, base, digits=None):
    """Convert integer `x` from base 10 to base `base` using `digits` characters as digits.
    If `digits` is omitted, it will use decimal digits + lowercase letters + uppercase letters.
    """
    digits = digits or (string.digits + string.ascii_letters)
    assert 2 <= base <= len(digits), "Unsupported base: {}".format(base)
    if x == 0:
        return digits[0]
    sign = '-' if x < 0 else ''
    x = abs(x)
    first_digits = base_convert(x // base, base, digits).lstrip(digits[0])
    return sign + first_digits + digits[x % base]
于 2016-12-09T08:53:51.370 回答
-1

字符串不是表示数字的唯一选择:您可以使用整数列表来表示每个数字的顺序。这些可以很容易地转换为字符串。

没有一个答案拒绝 base < 2;对于非常大的数字(例如 56789 ** 43210),大多数将运行非常缓慢或因堆栈溢出而崩溃。为避免此类故障,请像这样快速减少:

def n_to_base(n, b):
    if b < 2: raise # invalid base
    if abs(n) < b: return [n]
    ret = [y for d in n_to_base(n, b*b) for y in divmod(d, b)]
    return ret[1:] if ret[0] == 0 else ret # remove leading zeros

def base_to_n(v, b):
    h = len(v) // 2
    if h == 0: return v[0]
    return base_to_n(v[:-h], b) * (b**h) + base_to_n(v[-h:], b)

assert ''.join(['0123456789'[x] for x in n_to_base(56789**43210,10)])==str(56789**43210)

Speedwisen_to_basestr大数字相当(在我的机器上大约 0.3 秒),但如果你与之比较,hex你可能会感到惊讶(在我的机器上大约 0.3 毫秒,或者快 1000 倍)。原因是因为大整数以 256(字节)为基数存储在内存中。每个字节都可以简单地转换为两个字符的十六进制字符串。这种对齐只发生在 2 次方的碱基上,这就是为什么 2,8 和 16(以及 base64、ascii、utf16、utf32)有特殊情况的原因。

考虑十进制字符串的最后一位。它与构成其整数的字节序列有何关系?s[i]让我们用s[0]最不重要的字节(小端序)来标记字节。那么最后一个数字是sum([s[i]*(256**i) % 10 for i in range(n)])。好吧,碰巧 256**i 以 6 结尾,因为 i > 0 (6*6=36) 所以最后一个数字是(s[0]*5 + sum(s)*6)%10. 从中可以看出,最后一位数字取决于所有字节的总和。这种非本地属性使转换为十进制变得更加困难。

于 2017-01-19T14:34:04.283 回答
-1
num = input("number")
power = 0
num = int(num)
while num > 10:
    num = num / 10
    power += 1

print(str(round(num, 2)) + "^" + str(power))
于 2018-11-15T04:09:44.110 回答
-1

好吧我个人使用这个功能,由我编写

import string

def to_base(value, base, digits=string.digits+string.ascii_letters):    # converts decimal to base n

    digits_slice = digits[0:base]

    temporary_var = value
    data = [temporary_var]

    while True:
        temporary_var = temporary_var // base
        data.append(temporary_var)
        if temporary_var < base:
            break

    result = ''
    for each_data in data:
        result += digits_slice[each_data % base]
    result = result[::-1]

    return result

这就是你可以使用它的方式

print(to_base(7, base=2))

输出: "111"

print(to_base(23, base=3))

输出: "212"

请随时对我的代码提出改进建议。

于 2019-11-30T19:46:25.963 回答
-1

这是一个老问题,但我想我会分享我的看法,因为我觉得其他答案更简单(适用于 2 到 36 的基数):

def intStr(n,base=10):
    if n < 0   : return "-" + intStr(-n,base)         # handle negatives
    if n < base: return chr([48,55][n>9] + n)         # 48 => "0"..., 65 => "A"...
    return intStr(n//base,base) + intStr(n%base,base) # recurse for multiple digits
于 2020-04-29T16:36:51.873 回答
-1

我知道这是一篇旧帖子,但我只是将我的解决方案留在这里以防万一。

def decimal_to_given_base(integer_to_convert, base):
     remainder = integer_to_convert // base
     digit = integer_to_convert % base
     if integer_to_convert == 0:
         return '0'
     elif remainder == 0:
         return str(digit)
     else:
         return decimal_to_given_base(remainder, base) + str(digit)
于 2020-07-14T14:15:36.337 回答
-1

我做了我的功能来做到这一点。在 Windows 10、python 3.7.3 上运行良好。

def number_to_base(number, base, precision = 10):
    if number == 0:
        return [0]
    
    positive = number >= 0
    number = abs(number)
    
    ints = []  # store the integer bases
    floats = []  # store the floating bases

    float_point = number % 1
    number = int(number)
    while number:
        ints.append(int(number%base))
        number //= base
    ints.reverse()
    
    while float_point and precision:
        precision -= 1
        float_point *= base
        floats.append(int(float_point))
        float_point = float_point - int(float_point)

    return ints, floats, positive


def base_to_str(bases, string="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
    """bases is a two dimension list, where bases[0] contains a list of the integers,
    and bases[1] contains a list of the floating numbers, bases[2] is a boolean, that's
    true when it's a positive number
    """
    ints = []
    floats = []

    for i in bases[0]:
        ints.append(string[i])

    for i in bases[1]:
        floats.append(string[i])

    if len(bases[1]) > 0:
        return (["-", ""][bases[2]] + "".join(ints)) + "." + ("".join(floats))
    else:
        return (["-", ""][bases[2]] + "".join(ints))
    

    

例子:

>>> base_to_str(number_to_base(-6.252, 2))
'-110.0100000010'
于 2020-09-18T19:50:35.887 回答