Java 基于字节数组的Karatsuba乘法优化

Java 基于字节数组的Karatsuba乘法优化,java,arrays,algorithm,optimization,Java,Arrays,Algorithm,Optimization,我已经实现了双字节数组的乘法,它工作得很好。更准确地说,我需要将64字节的操作数与32字节的操作数相乘 我用最简单的方法实现它:我做一个双循环,然后计算每个数组中每个字节的乘积。 因此,对于特定值,需要64*32=2048个步骤 我试着用Karatsuba方法优化它。 因此,我采取以下方法: a的长度为64字节,b的长度为32字节 我们将a拆分为:a=p*16^32+q,因此p和q的长度都是32字节,并且compute:a*b=p*b*16^32+q*b产品使用前面描述的函数进行计算 我得到了正

我已经实现了双字节数组的乘法,它工作得很好。更准确地说,我需要将64字节的操作数与32字节的操作数相乘

我用最简单的方法实现它:我做一个双循环,然后计算每个数组中每个字节的乘积。 因此,对于特定值,需要64*32=2048个步骤

我试着用Karatsuba方法优化它。 因此,我采取以下方法:

a的长度为64字节,b的长度为32字节

我们将a拆分为:a=p*16^32+q,因此p和q的长度都是32字节,并且compute:a*b=p*b*16^32+q*b产品使用前面描述的函数进行计算

我得到了正确的结果,但计算需要相同的时间:两个32字节数组的2次乘法:32*32*2=64*32=2048

我的问题是:为了使用Karatsuba优化乘法,我应该完全递归地编程吗?换句话说,它永远不会更快


提前谢谢你:

哇!作为程序员,我的第一份工作之一是为COBOL运行时系统优化乘法算法——那是31年前的事了

我认为您会发现,所使用的技术是将字节组合成更大的单位。当时,只有32位可用,因此两个字节合并成一个短字节,短字节相乘得到一个32位整数。但在Java中,有64位可用,因此可以相乘两个整数得到一个长整数

因此,您应该通过添加字节来创建一个16整数的数组a1和一个8整数的数组b1。例如,有时像这样:

a1[0] = (a[0] << 24) + (a[1] << 16) + (a[2] << 8) + a[3]
或者您可以编写一个循环来更简洁地执行此操作

然后将a1和b1相乘,这需要128次运算

我会关注溢出和有符号值与无符号值。最高数字后面的数字应该是无符号的,但是Java没有无符号修饰符。但是,在Java8中,有一些对未签名操作的支持:请参阅


如果无法使整数/长数无符号工作,则始终可以将2或3个字节的组合并为整数,并浪费一些顶部位为符号位提供空间。

是的,Karatsuba算法只有在递归执行时才有效。但是请记住:Karatsuba并不总是比简单算法快,它采用^2。通常我们假设两个数字的长度相同,如果我们要乘以大的数字。对于小输入,它可以是1,也可以是15,这取决于您的CPU,简单算法可以更快,因此Karatsuba的最佳使用是:

如果KARATSUBA的大小>最小大小,你必须通过实验找到它,然后进行拆分并递归地调用KARATSUBA。
如果是size,为什么不使用biginger来表示大的数字呢,我用Java编程是为了在我的计算机上进行测试,但目的是在Java Card中切换。通常,你应该递归地编程,直到你得到足够小的子问题,迭代地解决它们会比递归地解决它们快,也就是说,对于Karatsuba来说,额外添加的成本将超过一个子问题的好处更少的乘法运算。对于Karatsuba乘法,截止点可能是三或四位数字,但它可能会根据您的实现而有所不同。例如,应用于不同问题的例子请看Timsort。通常,其他人无法告诉您问题的最佳解决方案是什么。相反,您应该熟悉现有的Java评测工具。。。然后仔细测量发生了什么。当然,需要递归的解决方案可能比避免额外方法调用的解决方案成本更高。即时编译器也可以在这里发挥作用。长话短说:衡量,不要假设。和:除非在处理实时性能要求时。。。代码的可读性通常比拥有100%的最高性能解决方案更重要。请看这里的一些想法。我担心这个问题与JavaCard实现有关,特别是在字节上使用Karatsuba算法。好的-谢谢。如果有兴趣,我会留下我的答案。它可能对那些想要优化字节数组算法的人有用。事实上,我想把它应用到JavaCard实现中,这样它就不适合它了。无论如何,这是一个很好的方法,谢谢你的提示