例如,我想计算(合理有效地)
2 ^ 1000003 mod 12321
最后我想做(2 ^ 1000003 - 3)mod 12321.有没有可行的方法来做到这一点?
答案 0 :(得分:3)
基本模数属性告诉我们
1)a + b (mod n)
为(a (mod n)) + (b (mod n)) (mod n)
,因此您可以分两步拆分操作
2)a * b (mod n)
为(a (mod n)) * (b (mod n)) (mod n)
,因此您可以使用模幂运算(伪代码):
x = 1
for (10000003 times) {
x = (x * 2) % 12321; # x will never grow beyond 12320
}
当然,你不应该做10000003次迭代,只记得2 1000003 = 2 * 2 1000002 ,2 1000002 = (2 500001 ) 2 等......
答案 1 :(得分:2)
以某种合理的C或类似Java的语言:
def modPow(Long base, Long exponent, Long modulus) = {
if (exponent < 0) {complain or throw or whatever}
else if (exponent == 0) {
return 1;
} else if (exponent & 1 == 1) { // odd exponent
return (base * modPow(base, exponent - 1, modulus)) % modulus;
} else {
Long halfexp = modPow(base, exponent / 2, modulus);
return (halfexp * halfexp) % modulus;
}
}
这要求modulus
足够小,(modulus - 1) * (modulus - 1)
和base * (modulus - 1)
都不会溢出您正在使用的整数类型。如果modulus
太大了,那么还有一些其他技术可以补偿一点,但用一些任意精度的整数算术库来攻击它可能更容易。
然后,你想要的是:
(modPow(2, 1000003, 12321) + (12321 - 3)) % 12321
答案 2 :(得分:-1)
在Java中,有一种简单的方法可以做到这一点:
Math.pow(2, 1000003) % 12321;
对于没有内置Math.*
功能的语言,它会变得有点困难。你能澄清一下这应该是哪种语言吗?