Algorithm 模化归约的Karatsuba乘法算法

Algorithm 模化归约的Karatsuba乘法算法,algorithm,multiplication,modular-arithmetic,Algorithm,Multiplication,Modular Arithmetic,我试图估算两个大位数乘以某个大素数所需的时间。我的计算能力仅限于加法、乘法和存储32位数字 由于这个原因,我想使用,因为乘法是减少到一位数的运算。然而,该算法不包含模块化约简 我的另一个想法是使用,但考虑到我的计算限制,我不确定这将如何执行 您建议我使用哪种算法?这不是答案,但在评论中无法阅读 这只是说明Karatsuba代码的样子 这是我对任意浮点数的Karatsuba乘法的实现 dat[siz]是mantisa LSDW表示最低有效DWORD exp是dat[0]的MSB的指数 mantis

我试图估算两个大位数乘以某个大素数所需的时间。我的计算能力仅限于加法、乘法和存储32位数字

由于这个原因,我想使用,因为乘法是减少到一位数的运算。然而,该算法不包含模块化约简

我的另一个想法是使用,但考虑到我的计算限制,我不确定这将如何执行


您建议我使用哪种算法?

这不是答案,但在评论中无法阅读

这只是说明Karatsuba代码的样子 这是我对任意浮点数的Karatsuba乘法的实现

dat[siz]是mantisa LSDW表示最低有效DWORD exp是dat[0]的MSB的指数 mantisa中存在第一个非零位

// |-----|---------------------------|---------------|------|
// | sig | MSB      mantisa      LSB |   exponent    | bits |
// |-----|---------------------------|---------------|------|
// | +1  | 0.(0      ...          0) | 2^0           |   0  | +zero
// | -1  | 0.(0      ...          0) | 2^0           |   0  | -zero
// |-----|---------------------------|---------------|------|
// | +1  | 1.(dat[0] ... dat[siz-1]) | 2^exp         |   n  | +number
// | -1  | 1.(dat[0] ... dat[siz-1]) | 2^exp         |   n  | -number
// |-----|---------------------------|---------------|------|
// | +1  | 1.0                       | 2^+0x7FFFFFFE |   1  | +infinity
// | -1  | 1.0                       | 2^+0x7FFFFFFE |   1  | -infinity
// |-----|---------------------------|---------------|------|

karatsuba不是个位数!相反,它使用更多的数字大小。。。从1到~solution_digits/2,因此需要可变位大小的算法。如果您只有非常大的数字,并且不想实现可变的位宽算术,那么我将使用基于NTT变换的Schönhage-Strassen乘法,对于小数字使用naive on^2multiplication@Spektre根据Karatsuba算法的维基百科页面,它通常将两个n位数的乘法减少到最多n^1.585个单位数的乘法。这是不对的吗?是的,这可能是对的,但karatsuba从1位运算开始,然后是2位运算,然后是4位运算。。。。所以你需要可变数字算法,而不仅仅是32位来实现这一点。可以从32位ALU块对其进行编码,但当我尝试对其进行编码时,这会减慢速度递归会大大减慢速度,如果您不知道自己在做什么,编码可能会变得复杂。。。另一方面,您可以将操作限制为模素数,这不是我的案例,使用我的karatsuba实现添加了非答案,因此您明白我的意思……请详细说明[尾数]每个32位块的上/下溢LSB。在LSDW中也会发生这种情况吗?@greybeard我添加了错误示例来回答。。。我也错了,错误可以在20*32位操作数上传播,我曾经在第1位看到过。我现在看不到LSDW中的错误,但我认为它在我过去做的一些测试中存在,但现在不确定……想想看:x0+x1y0+y1 mod 2^N。cx和cy都非零的情况如何?这难道不需要两个增量或相等的增量吗?由_潜艇的航次适时更新。要么在z中处理这些,要么将*p扩展一个。@greybeard哇,谢谢你,伙计,你明白了。。。。不管我在这上面花了多长时间,我都会记住那一点。在几分钟内根据您的评论修复了代码:如果所讨论的阶段溢出,则添加另一个增量并不意味着哪个部分看起来适用于所有场景无、一个和两个操作溢出,因此现在结果与所有其他乘法实现匹配。再次感谢。它可以通过合并最后的增量来进一步优化。。。还修复了MSDW/LSDW顺序在文本中被颠倒…@greybeard我还更新了这里的代码
// dat is MSDW first ... LSDW last
DWORD *dat; int siz,exp,sig,bits;
// |-----|---------------------------|---------------|------|
// | sig | MSB      mantisa      LSB |   exponent    | bits |
// |-----|---------------------------|---------------|------|
// | +1  | 0.(0      ...          0) | 2^0           |   0  | +zero
// | -1  | 0.(0      ...          0) | 2^0           |   0  | -zero
// |-----|---------------------------|---------------|------|
// | +1  | 1.(dat[0] ... dat[siz-1]) | 2^exp         |   n  | +number
// | -1  | 1.(dat[0] ... dat[siz-1]) | 2^exp         |   n  | -number
// |-----|---------------------------|---------------|------|
// | +1  | 1.0                       | 2^+0x7FFFFFFE |   1  | +infinity
// | -1  | 1.0                       | 2^+0x7FFFFFFE |   1  | -infinity
// |-----|---------------------------|---------------|------|