我现在正在学习Pascal一个月了,我遇到了一个似乎无法解决的问题。基本上我有2个数字, N 和 M ,其中 N 小于10 100 000 和 M 小于10 8 且都大于0.我需要计算 N mod M 。
我无法弄清楚如何做到这一点,甚至不能用QWord
。我用string
尝试过,但我不知道一个好方法。它总是对我来说太复杂了,因为我使用了for
函数,我从字符串 N 得到最后一个数字,字符串 M 然后我用它减去它们两个if
函数(其中 N 的最后一位数字高于或等于 M 的最后一位,如果它更低)。基本上,我认为这个简单的问题太复杂了。
答案 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毫秒。