Python 如何将整数转换为任意基中的字符串?
Python允许从给定基的字符串通过Python 如何将整数转换为任意基中的字符串?,python,base,radix,Python,Base,Radix,Python允许从给定基的字符串通过 int(str, base). 我要执行反向操作:从整数创建字符串, i、 e.我需要一些函数int2base(num,base),例如: int(int2base(x, b), b) == x 函数名/参数顺序不重要 对于int()将接受的任何数字x和基b 这是一个很容易编写的函数:事实上,它比在这个问题中描述它更容易。然而,我觉得我肯定错过了什么 我知道函数bin,oct,hex,但我无法使用它们,原因如下: 这些函数在较早版本的Python上不
int(str, base).
我要执行反向操作:从整数创建字符串,
i、 e.我需要一些函数int2base(num,base)
,例如:
int(int2base(x, b), b) == x
函数名/参数顺序不重要
对于int()
将接受的任何数字x
和基b
这是一个很容易编写的函数:事实上,它比在这个问题中描述它更容易。然而,我觉得我肯定错过了什么
我知道函数bin
,oct
,hex
,但我无法使用它们,原因如下:
- 这些函数在较早版本的Python上不可用,我需要与(2.2)兼容
- 我想要一个通用的解决方案,可以被称为不同的基地相同的方式
- 我想允许2,8,16以外的基数
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 baseconvert(n,base):
“”“将正十进制整数n转换为另一个基数(2-36)中的等效数”
digits=“0123456789abcdefghijklmnopqrstuvxyz”
尝试:
n=int(n)
base=int(base)
除:
返回“”
如果n<0或基数<2或基数>36:
返回“”
s=“”
而1:
r=n%基准
s=数字[r]+s
n=n/基
如果n==0:
打破
返回s
def baseN(num,b,numbers=“0123456789abcdefghijklmnopqrstuvwxyz”):
返回((num==0)和数字[0])或(baseN(num//b,b,数字)。lstrip(数字[0])+数字[num%b])
参考:
请注意,这可能导致
RuntimeError: maximum recursion depth exceeded in cmp
对于非常大的整数。如果需要与Python的古代版本兼容,可以使用(它确实包含一个快速、完全通用的int-to-string转换函数,并且可以为这种古老的版本构建——您可能需要尝试较旧的版本,因为最近的版本没有针对古老的Python和GMP版本进行测试,只有一些较新的版本),或者,为了更快更方便,使用Python代码–例如,最简单的方法是:
导入字符串
digs=string.digits+string.ascii_字母
def int2base(x,基本):
如果x<0:
符号=-1
elif x==0:
返回挖掘[0]
其他:
符号=1
x*=符号
数字=[]
而x:
数字。追加(数字[int(x%基数)])
x=int(x/基)
如果符号<0:
数字。追加('-'))
数字。反向()
返回“”。连接(数字)
答案很棒!
我想我的问题的答案是“不”,我没有遗漏一些明显的解决办法。
下面是我将使用的函数,它浓缩了答案中表达的好想法
- 允许调用方提供的字符映射(允许base64编码)
- 检查负和零
- 将复数映射为字符串的元组
def int2base(x,b,字母表='0123456789ABCDEFGHIJKLMNOPQRSTUVXYZ'):
'将整数转换为给定基中的字符串表示形式'
如果是blen(字母表):
如果b==64:#假设base64而不是引发错误
alphabet=“abcdefghijklmnopqrstuvxyzabefghijklmnopqrstuvxyzo123456789+/”
其他:
引发断言错误(“int2base base超出范围”)
如果isinstance(x,复数):#返回一个元组
返回(int2base(x.real,b,字母表),int2base(x.imag,b,字母表))
如果x0:
x、 idx=divmod(x,b)
rets=字母表[idx]+rets
返回rets
您可以使用我的项目中的baseconv.py
:
示例用法:
>>> 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.base2
,baseconv.base16
和baseconv.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)
输出:
“1F”
对于那些感兴趣的人来说,这是一个递归解决方案。当然,这对负二进制值不起作用。您需要实现二的补码
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
def generateBase36Alphabet():
返回“”。加入([str(i)表示范围(10)中的i)]+[chr(i+65)表示范围(26)])
def generateAlphabet(基本):
返回generateBase36Alphabet()[:base]
def intToStr(n,基数,字母):
def toStr(n,基数,字母):
如果n {}.”格式(-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-102577)
将为您提供正确的解决方案:
[4473131,9643128524486,28,23,16,8229253814925,4148310017131,28,0435197264455]
你以后可以把它转换成你想要的任何基。我为此做了一个pip包
我建议您使用受base.js启发的my base.py
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
指
什么样的基础是可用的
编辑:
pip链接另一个简短的链接(更容易理解imo):
并在适当的异常处理下:
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")
解释
在任何基数中,每个数字都等于a1+a2*基数**2+a3*基数**3…
的“任务”是找到所有a
对于每一个N=1,2,3…
代码通过b为b=base**(N+1)
的“moudiling”来隔离aN*base**N
,这将切片所有a大于N,并通过每次当前aN*base**N调用函数时减少a来切片其序列小于N的所有a
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
def numberToBase(n, b):
if n == 0:
return [0]
digits = []
while n:
digits.append(int(n % b))
n //= b
return digits[::-1]
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
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()
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]
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)
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]
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'
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
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 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)
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'