如何将整数转换为任何基数的字符串?

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

int(str, base).
我想要执行逆:从整数创建字符串, 例如,我想要一些函数int2base(num, base),这样:

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

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

对于int()将接受的任何数字x和基数b

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

我知道函数binocthex,但由于一些原因我不能使用它们:

  • 这些函数在旧版本的Python中不可用,我需要与(2.2)兼容

  • 我想要一个通解对于不同的碱都可以用同样的方式表示

  • 我想允许2 8 16以外的底数

相关的

351658 次浏览

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
def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])
< p >参考: http://code.activestate.com/recipes/65212/ < / p >

请注意这可能会导致

RuntimeError: maximum recursion depth exceeded in cmp

对于非常大的整数。

如果你需要兼容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)
>>> 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'
< p >很棒的答案! 我想我问题的答案是“不”,我并没有错过一些明显的解决方案。 下面是我将使用的函数,它浓缩了答案中所表达的好想法
  • 允许调用者提供的字符映射(允许base64编码)
  • 检查负数和零
  • 将复数映射为字符串元组
以前< p > < > <代码> def int2base (x、b字母表= 0123456789 abcdefghijklmnopqrstuvwxyz): '将整数转换为给定进制中的字符串表示形式' 如果b<2或b>len(字母表): 如果b==64: #假设base64而不是抛出错误 字母= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 其他: 抛出AssertionError("int2base base out of range") 如果isinstance(x,complex): #返回一个元组 返回(int2base(x.real,b,alphabet), int2base(x.imag,b,alphabet)) 如果x< = 0: 如果x = = 0: 返回字母[0] 其他: 返回'-' + int2base(-x,b,字母表) # else x是非负实数 ret = " 而x > 0: X,idx = divmod(X,b) Rets =字母表[idx] + Rets 返回ret < / p >

< /代码> < / >之前

"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144

你可以使用我的项目中的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'

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

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)

输出:

“1 f”

一个递归的解决方案。当然,这对负二进制值不起作用。您需要实现Two's Complement。

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

令人惊讶的是,人们给出的答案只能转换成小基数(比英语字母表的长度还小)。没有人试图给出一个可以转换为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], < / p >

你以后可以把它转换成任何你想要的基数

  1. 有时你会注意到,有时候没有内置的库函数来做你想做的事情,所以你需要自己编写。如果你不同意,发布你自己的解决方案,内置函数可以将十进制数字转换为577。
  2. 这是由于缺乏理解在某些基数中的数字意味着什么。
  3. 我鼓励你们思考一下为什么你的方法中底数只适用于n <= 36。一旦你完成了,很明显为什么我的函数返回一个列表,并具有它的签名。

我为此做了一个小包裹。

我建议你使用我的bases.py https://github.com/kamijoutouma/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/kamijoutouma/bases.py#known-basesalphabets

< p >编辑: pip link https://pypi.python.org/pypi/bases.py/0.2.2

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]

另一个简短的(在我看来更容易理解):

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")
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。

对于每个__abc0,代码通过“mouduling"对于b=base**(N+1),通过b对所有大于N的a进行切片,并在当前aN*base**N每次调用该函数时减少a,对所有序列小于N的a进行切片。

Base%(Base -1)==1,则Base **p%(Base -1)==1,因此q* Base ^p%(Base -1)==q,只有当q= Base -1返回0时例外。 为了解决这个问题,如果它返回0,func将检查它从原点到原点是否为0


优势

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

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

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]

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

没有一个答案拒绝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)

在速度方面,n_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恰好以i > 0(6*6=36)的6结尾,所以最后一位是(s[0]*5 + sum(s)*6)%10。由此可以看出,最后一位数字取决于所有字节的和。这个非局部属性使得转换为十进制更加困难。

num = input("number")
power = 0
num = int(num)
while num > 10:
num = num / 10
power += 1


print(str(round(num, 2)) + "^" + str(power))

递归

我将简化 投票最多的答案到:

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也有相同的建议。(你可以使用__abc2)

迭代

避免递归问题:

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(s, b):
res = ""
while s:
res+=BS[s%b]
s//= b
return res[::-1] or "0"
>>> numpy.base_repr(10, base=3)
'101'

注意numpy.base_repr()的底数限制为36。否则抛出ValueError

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]

我个人使用我写的这个函数

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))

< p >输出: "111" < / p >

print(to_base(23, base=3))

< p >输出: "212" < / p >

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

下面是一个如何将任意基数转换为另一个基数的示例。

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!!!")
def base_conversion(num, base):
digits = []
while num > 0:
num, remainder = divmod(num, base)
digits.append(remainder)
return digits[::-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

我知道这是一个老帖子,但我只是把我的解决方案留在这里以防万一。

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)

我让函数这样做。在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'

假设我们想把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]

这就是我的方法。首先转换数字,然后将其转换为字符串。

    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)

我写了这个函数,我用它来编码不同的碱基。我还提供了通过值“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()

这个函数将任意整数从任意进制转换为任意进制

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)
下面提供的Python代码将Python整数转换为任意进制的字符串(从2到无穷),并双向工作。因此,通过为N提供字符串而不是整数,所有创建的字符串都可以转换回Python整数。 代码只对正数有效(在我看来,负数和它们的位表示有一些麻烦,我不想深入研究)。只需从这些代码中选择您需要、想要或喜欢的内容,或者只是愉快地学习可用的选项。这里有很多只是为了记录所有各种可用的方法(例如,onlineer似乎并不快,即使承诺是)

我喜欢萨尔瓦多·达利提出的无限大基地的格式。一个很好的建议,它在光学上工作得很好,即使是简单的二进制位表示。注意,在infiniteBase=True格式的字符串的情况下,width=x填充参数适用于数字,而不是整个数字。似乎,代码处理无穷大数字格式运行甚至比其他选项快一点-使用它的另一个原因?

我不喜欢使用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

我呈现的是一个“未优化的”;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

这个解决方案不需要反转最终结果,但实际上并没有优化。参考这个答案来了解原因:https://stackoverflow.com/a/37133870/7896998

简单基底变换

def int_to_str(x, b):
s = ""
while x:
s = str(x % b) + s
x //= b
return s

输出的例子,没有0到基数9

s = ""
x = int(input())
while x:
if x % 9 == 0:
s = "9" + s
x -= x % 10
x = x // 9
else:
s = str(x % 9) + s
x = x // 9


print(s)

虽然目前上面的回答确实是一个很棒的解决方案,但仍然有更多用户可能喜欢的定制。

Basencode添加了其中的一些特性,包括浮点数的转换,修改数字(在链接的答案中,只能使用数字)。

下面是一个可能的用例:

>>> from basencode import *
>>> n1 = Number(12345)
>> n1.repr_in_base(64) # convert to base 64
'30V'
>>> Number('30V', 64) # construct Integer from base 64
Integer(12345)
>>> n1.repr_in_base(8)
'30071'
>>> n1.repr_in_octal() # shortcuts
'30071'
>>> n1.repr_in_bin() # equivelant to `n1.repr_in_base(2)`
'11000000111001'
>>> n1.repr_in_base(2, digits=list('-+')) # override default digits: use `-` and `+` in place of `0` and `1`
'++------+++--+'
>>> n1.repr_in_base(33) # yet another base - all bases from 2 to 64 are supported from the start
'bb3'

你怎么添加你想要的碱基?让我复制一下目前投票最多的答案的例子:digits参数允许你覆盖从2到64的默认数字,并为任何高于这个基数的数字提供数字。mode参数决定了表示的值将如何决定(列表或字符串)将如何返回答案。

>>> n2 = Number(67854 ** 15 - 102)
>>> n2.repr_in_base(577, digits=[str(i) for i in range(577)], mode="l")
['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']
>>> n2.repr_in_base(577, mode="l") # the program remembers the digits for base 577 now
['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']

可以执行以下操作:如果提供的数字是Integer, Number类返回basencode.Integer的实例,否则返回basencode.Float

>>> n3 = Number(54321) # the Number class returns an instance of `basencode.Integer` if the provided number is an Integer, otherwise it returns a `basencode.Float`.
>>> n1 + n3
Integer(66666)
>>> n3 - n1
Integer(41976)
>>> n1 * n3
Integer(670592745)
>>> n3 // n1
Integer(4)
>>> n3 / n1 # a basencode.Float class allows conversion of floating point numbers
Float(4.400243013365735)
>>> (n3 / n1).repr_in_base(32)
'4.cpr56v6rnc4oitoblha2r11sus0dheqd4pgechfcjklo74b2bgom7j8ih86mipdvss0068sehi9f3791mdo4uotfujq66cf0jkgo'
>>> n4 = Number(0.5) # returns a basencode.Float
>>> n4.repr_in_bin() # binary version of 0.5
'0.1'

免责声明:此项目正在积极维护中,我是贡献者。