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安全字符串?
一个递归的解决方案。当然,这对负二进制值不起作用。您需要实现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
一个递归的解决方案。当然,这对负二进制值不起作用。您需要实现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
我让函数这样做。在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'
令人惊讶的是,人们给出的答案只能转换成小基数(比英语字母表的长度还小)。没有人试图给出一个可以转换为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],
你以后可以把它转换成任何你想要的基数
at some point of time you will notice that sometimes there is no built-in library function to do things that you want, so you need to write your own. If you disagree, post you own solution with a built-in function which can convert a base 10 number to base 577.
this is due to lack of understanding what a number in some base means.
I encourage you to think for a little bit why base in your method works only for n <= 36. Once you are done, it will be obvious why my function returns a list and has the signature it has.