我需要创建一个优化函数来计算Javascript中的 Math.pow(a,b)%c; ;
在计算小数字时没有问题:
Math.pow(2345,123) % 1234567;
但是如果你试图计算:
Math.pow(2345678910, 123456789) % 1234567;
由于Math.pow()函数结果无法统计“大”数字,你会得到错误的结果;
我的解决方案是:
function powMod(base, pow, mod){
var i, result = 1;
for ( i = 0; i < pow; i++){
result *= base;
result %= mod;
}
return result;
虽然需要很多时间才能计算; 是否有可能以某种方式优化它或找到更合理的方式来计算 Math.pow(a,b)%c; 的“大”数字? (我写的是“大”,因为他们不是真正的大事);
答案 0 :(得分:11)
基于SICP。
function expmod( base, exp, mod ){
if (exp == 0) return 1;
if (exp % 2 == 0){
return Math.pow( expmod( base, (exp / 2), mod), 2) % mod;
}
else {
return (base * expmod( base, (exp - 1), mod)) % mod;
}
}
这个应该比第一次供电更快,然后取余数,因为每次乘法时它都需要余数,从而使实际数字保持相对较小。
答案 1 :(得分:2)
到目前为止,您的方法很好,但您需要http://en.wikipedia.org/wiki/Exponentiation_by_squaring也称为http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
我的想法是x^45
与(扩展为二进制)x^(32+8+4+1)
相同,与x^32 * x^8 * x^4 * x^1
首先计算x^1
,然后x^2 == (x^1)^2
,然后计算x^4 == (x^2)^2
,然后计算x^8 == (x^4)^2
,然后......
答案 2 :(得分:1)
你也可以将mountgomery简化与指数结合使用,这对于大指数来说非常有用&gt; 256:
http://en.wikipedia.org/wiki/Montgomery_reduction#Modular_exponentiation
此BigInteger库中也实现了RSA加密: