Python允许从给定基数的字符串中轻松创建一个整数

int(str, base). 

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

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

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

对于int()将接受的任何以b为底的数字x。

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

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

这些函数在旧版本的Python中不可用,我需要与(2.2)兼容 我想要一个通解对于不同的碱都可以用同样的方式表示 我想允许2 8 16以外的底数

相关的

Python优雅的int(string, base)逆函数 在python中使用递归的整数到base-x系统 Python中的Base 62转换 如何在Python中将整数转换为最短的url安全字符串?


当前回答

我写了这个函数,我用它来编码不同的碱基。我还提供了通过值“offset”来移动结果的方法。如果你想编码到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()

其他回答

如果你需要兼容Python的古老版本,你可以使用gmpy(它包含一个快速的,完全通用的int-to-string转换函数,可以为这样的古老版本构建-你可能需要尝试更老的版本,因为最近的版本还没有针对古老的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)

我让函数这样做。在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'
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)
def baseConverter(x, b):
    s = ""
    d = string.printable.upper()
    while x > 0:
        s += d[x%b]
        x = x / b
    return s[::-1]

假设我们想把14转换成2进制。我们反复应用除法算法,直到商为0:

14 = 2 × 7

7 = 2 × 3 + 1

3 = 2 × 1 + 1

1 = 2 × 0 + 1

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

14 = 2 × 7 = 2 × (2 × 3 + 1) = 2 × (2 × (2 × 1 + 1) + 1) = 2 × (2 × (2 × 0 + 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]