关于karatsuba乘法的问题

时间:2011-09-18 12:28:29

标签: python algorithm math

我想在Python中实现Karatsuba's 2-split multiplication。但是,以表格

编写数字
A=c*x+d

其中x是基数(令x = b ^ m)接近sqrt(A)的幂。

如果我甚至不能使用除法和乘法,我该如何找到x?我应该计算位数并将A向左移动一半的位数吗?

感谢。

3 个答案:

答案 0 :(得分:4)

几乎。你不要将A移位数字的一半;你移位1.当然,这只有在基数是2的幂时才有效,因为基数10(例如)中的“移位”必须用乘法来完成。 (编辑:好吧,好吧,你可以乘以班次和加法。但它的功能更加简单,功能为2。)

如果您使用的是Python 3.1或更高版本,则计算位很容易,因为3.1引入了int.bit_length()方法。对于其他版本的Python,您可以通过复制A并将其向右移动直到它为0来对位进行计数。这可以在O(log N)时间(N =数字的数字)中使用一种二进制搜索方法完成 - 转换为很多位,如果它是0则那么太多,等等。

答案 1 :(得分:3)

自从我开始写这篇文章以来,你已经接受了答案,但是:

汤姆说:在Python 3.x中你可以直接得到n = int.bit_length()。 在Python 2.x中,你通过二进制搜索得到n(log2(A))时间,如下所示。

这是计算两者的(2.x)代码。设x的base-2指数为n,即x = 2 ** n。

首先,通过移位进行二元搜索得到n。 (实际上我们只需要n / 2,所以这是一次不必要的最后一次迭代)。 然后当我们知道n时,获得x,c,d很容易(仍然没有使用除法)

def karatsuba_form(A,n=32):
    """Binary-search for Karatsuba form using binary shifts"""
    # First search for n ~ log2(A)
    step = n >> 1
    while step>0:
        c = A >> n
        print 'n=%2d step=%2d -> c=%d' % (n,step,c)
        if c:
            n += step
        else:
            n -= step
        # More concisely, could say: n = (n+step) if c else (n-step)
        step >>= 1
    # Then take x = 2^(n/2) ˜ sqrt(A)
    ndiv2 = n/2
    # Find Karatsuba form
    c = (A >> ndiv2)
    x = (1 << ndiv2)
    d = A - (c << ndiv2)
    return (x,c,d)

答案 2 :(得分:2)

您提到的文章已经回答了您的问题:“Karatsuba的基本步骤适用于任何基数B和任何m,但当m等于n / 2时,递归算法效率最高,向上舍入”.. 。n是位数,0&lt; = value_of_digit&lt;乙

可能有所帮助的一些观点:

您被允许(并且必须!)在学校算术中使用基本操作,例如number_of_digits // 2divmod(digit_x * digit_x, B) ...,其中B为10,您需要(例如)知道divmod(9 * 8, 10)生成(7, 2)

在计算机上实现大数字运算时,通常使B成为2的最大幂,可以方便地支持基本乘法运算。例如,在32位机器上的CPython实现中,B被选择为2 ** 15(即32768),因为product = digit_x * digit_y; hi = product >> 15; lo = product & 0x7FFF;工作时没有溢出而没有关注符号位。

我不确定你在Python中使用B == 2实现了什么,数字由Python int表示,其在C中的实现已经使用Karatsuba算法来乘以足够大的数字让它值得。它不可能是速度。

作为学习练习,您可能希望尝试将数字表示为数字列表,其中基数B是输入参数。

相关问题