如何计算一个这么大的数字?

时间:2014-02-17 20:22:10

标签: pascal modulus bignum

我现在正在学习Pascal一个月了,我遇到了一个似乎无法解决的问题。基本上我有2个数字, N M ,其中 N 小于10 100 000 M 小于10 8 且都大于0.我需要计算 N mod M

我无法弄清楚如何做到这一点,甚至不能用QWord。我用string尝试过,但我不知道一个好方法。它总是对我来说太复杂了,因为我使用了for函数,我从字符串 N 得到最后一个数字,字符串 M 然后我用它减去它们两个if函数(其中 N 的最后一位数字高于或等于 M 的最后一位,如果它更低)。基本上,我认为这个简单的问题太复杂了。

1 个答案:

答案 0 :(得分:3)

有一些bignum包漂浮在周围,例如来自http://www.wolfgang-ehrhardt.de/mp_intro.html的开源MPArith包。使用随附的演示计算器,您可以轻松超越时间限制:

D:\Xtools\MPArith>t_calc.exe
T_CALC using MPArith V1.26.05 (31/32 bit) [mp_calc]  (c) W.Ehrhardt 2006-2013
Karatsuba cutoffs:  mul/sqr = 16/32,   Toom-3 cutoffs: mul/sqr = 32/64
Burnikel/Ziegler div cutoff = 32,   MaxBit = 520093696,   MaxFact = 22623931
Type "?<enter>" to get some info about commands, "\q" or "quit" to end.

[D]:=> 10^100000 mod (10^8-1)
Result = 1
[D]:=> .
Time = 20.128 ms
[D]:=> 10^100000;
Result =  [>0, 332193 bits,  chksum=$CE01C341,  time=46.994 ms]

但根据您的要求和示例,您甚至可以获得结果 没有 bignum套餐。如果您想计算a ^ b mod n不要 计算 a ^ b,然后在第二步中减少mod n,但减少循环中的每个产品。和 你应该使用快速二进制取幂,参见例如描述和伪 代码http://en.wikipedia.org/wiki/Modular_exponentiation。 对于10 ^ 8阶的模块n,您需要减少两个31/32位整数的乘积 因此,您需要int64左右来积累产品(对于具有QWord的Pascal版本而言,这不应该是一个问题)。我想这样的程序会比MPArith bignum快得多 使用它的代码是20毫秒。