我们有一个非常大的数字,类似于(10**1500000)+1,并希望将其转换为3进制。以下是我们在普通Python中发现的最快方法的运行代码(不使用numpy或CAS库)。
如何加速底数转换(转换为3进制)的性能?
我们想知道以下两种方式中都可以如何实现:
1.仅使用Python 3的内置函数(无numpy)? 2.从正常的Python 3程序中使用numpy(或其他CAS库)?
欢迎任何帮助。这是我们目前的代码:
在如何尽快计算一个大于一百万位的十进制整数的三进制值?中有一个类似的问题,但在基本转换之前需要进行更多的步骤。 在这个问题中,我们集中讨论了远远占用时间的部分,并且我们还没有得到答案。
此外,在将十进制数转换为三进制数中,没有涉及到处理大数的性能方面。
如何加速底数转换(转换为3进制)的性能?
我们想知道以下两种方式中都可以如何实现:
1.仅使用Python 3的内置函数(无numpy)? 2.从正常的Python 3程序中使用numpy(或其他CAS库)?
欢迎任何帮助。这是我们目前的代码:
#### --- Convert a huge integer to base 3 --- ####
# Convert decimal number n to a sequence of list elements
# with integer values in the range 0 to base-1.
# With divmod, it's ca. 1/3 faster than using n%b and then n//=b.
def numberToBase(n, b):
digits = []
while n:
n, rem = divmod(n, b)
digits.append(rem)
return digits[::-1]
# Step 2: Convert given integer to another base
# With convsteps == 3, it's about 50-100 times faster than
# with with convsteps == 1, where numberToBase() is called only once.
def step2(n, b, convsteps):
nList = []
if convsteps == 3: # Here the conversion is done in 3 steps
expos = 10000, 300
base_a = b ** expos[0]
base_b = b ** expos[1]
nList1 = numberToBase(n, base_a) # time killer in this part
nList2 = [numberToBase(ll, base_b) for ll in nList1]
nList3 = [numberToBase(mm, b) for ll in nList2 for mm in ll]
nList = [mm for ll in nList3 for mm in ll]
else: # Do conversion in one bulk
nList = numberToBase(n, b) # that's the time killer in this part
return nList
if __name__ == '__main__':
int_value = (10**1500000)+1 # sample huge numbers
# expected begin: [2, 2, 0, 1, 1, 1, 1, 0, 2, 0]
# expected time: 4 min with convsteps=3
base = 3
# Convert int_value to list of numbers of given base
# -- two variants of step2() using different convsteps params
numList = step2(int_value, base, convsteps=1)
print(' 3-1: numList begin:', numList[:10])
# A value of '3' for the parameter "convsteps" makes
# step2() much faster than a value of '1'
numList = step2(int_value, base, convsteps=3)
print(' 3-3: numList begin:', numList[:10])
在如何尽快计算一个大于一百万位的十进制整数的三进制值?中有一个类似的问题,但在基本转换之前需要进行更多的步骤。 在这个问题中,我们集中讨论了远远占用时间的部分,并且我们还没有得到答案。
此外,在将十进制数转换为三进制数中,没有涉及到处理大数的性能方面。
yield
是否比list.append
更快?你也可以尝试将字符串反转而不是列表。 - Mark Ransomn = 10**30000 + 1
,n = 10**80000 + 1
和其他大数值,我从numberToBase(n, 3)
和step2(n, 3, 3)
得到了不同的结果;答案长度也不同。我认为在convsteps == 3
代码中组装结果的方式存在错误,因为对结果开头和结尾数字的目测检查表明它们是一致的。 - Warren Weckessergmpy2
的大数库包装器;例如gmpy2.digits(your_num, 3)
,即使与设计良好的纯 Python 替代方案相比,也能提高几个数量级。 - DSM