Python 长整数乘法

4 投票
4 回答
18067 浏览
提问于 2025-04-15 16:37

我需要一个比现在普通的Python长乘法更快的算法。

我试着找一个不错的Karatsuba算法实现,但没找到。

def main():
    a=long(raw_input())
    if(a<0):
        a=a*-1
        a=((a*(a+1)/2)-1)
        print(-a)
    else:
        a=(a*(a+1))/2
        print(a)
main()

如你所见,这个算法并不复杂,只是几个乘法运算。但它必须能在2.5秒内处理最多100000位的数字。

我希望能得到一些函数的代码片段,或者链接到一些更快的乘法函数实现,或者任何有帮助的东西。

4 个回答

9

在我这台慢笔记本上,运行需要15.9毫秒。打印的过程让你变慢了。把二进制数字转换成十进制的过程比较慢,而这个转换是打印输出的必要步骤。如果你需要输出这个数字,建议试试DecInt,正如ChristopheD提到的。

虽然DecInt在乘法运算时会慢一些,但打印的速度会快很多。

In [34]: a=2**333000

In [35]: len(str(a))
Out[35]: 100243

In [36]: b=2**333001

In [37]: len(str(b))
Out[37]: 100244

In [38]: timeit c=a*b
10 loops, best of 3: 15.9 ms per loop

这里有一个稍微修改过的代码示例。请注意,把一个包含100000个数字的字符串转换成长整型,在这台电脑上已经需要大约1秒钟。

In [1]: def f(a):
   ...:     if(a<0):
   ...:         a=a*-1
   ...:         a=((a*(a+1)/2)-1)
   ...:     else:
   ...:         a=(a*(a+1))/2
   ...:     return a
   ...: 

In [2]: a=3**200000

In [3]: len(str(a))
Out[3]: 95425

In [4]: timeit f(a)
10 loops, best of 3: 417 ms per loop
27

我是DecInt(十进制整数)库的作者,所以我想说几句。

DecInt库是专门为处理非常大的整数而设计的,这些整数需要转换成十进制格式。转换成十进制格式的问题在于,大多数任意精度的库都是用二进制来存储数值。虽然这样做在内存使用上最快最有效,但从二进制转换到十进制通常比较慢。比如,Python的二进制转十进制的过程使用的是O(n^2)的算法,速度会很快变慢。

DecInt使用一个很大的十进制基数(通常是10^250),并将非常大的数字分成250位一块来存储。这样,把一个非常大的数字转换成十进制格式的速度就变成了O(n)。

普通的乘法(就像小学学的那样)运行时间是O(n^2)。而Python使用的是Karatsuba乘法,运行时间是O(n^1.585)。DecInt则结合了Karatsuba、Toom-Cook和Nussbaumer卷积,运行时间达到了O(n*ln(n))。

虽然DecInt的开销更高,但O(n*ln(n))的乘法和O(n)的转换组合起来,最终会比Python的O(n^1.585)乘法和O(n^2)转换要快。

因为大多数计算并不需要每个结果都显示为十进制格式,所以几乎所有的任意精度库都使用二进制,这样计算会更简单。DecInt的目标是一个非常小的细分市场。对于足够大的数字,DecInt在乘法和除法上会比Python原生的快。但如果你追求纯粹的性能,像GMPY这样的库会更快。

我很高兴你觉得DecInt有帮助。

2

你可以看看这个 DecInt模块 的实现(有纯Python版本可用(Toom-Cook),不过用 gmpy 的话,速度可能会更快)。

撰写回答