任何人都知道如何在java中实现这样的问题?
“实现一个带有三个正整数参数(a; b; n)的子程序并返回 值的((a到b的幂)mod n),其中参数由大约100个十进制数字表示。使用四种不同的方法。“
提前致谢
UPD:方法如下
M1)
public BigInteger Result1(BigInteger a , BigInteger b , BigInteger n){
BigInteger Res = new BigInteger("1");
for (BigInteger i = new BigInteger("0"); !i.equals(b); i = i.add(new BigInteger("1"))) {
Res = Res.multiply(a).mod(n);
}
return Res;
}
M2)
public BigInteger Result2(BigInteger a , BigInteger b , BigInteger n){
BigInteger Res = new BigInteger("1");
for (BigInteger i = new BigInteger("0"); !i.equals(b); i = i.add(new BigInteger("1"))) {
Res = Res.multiply(a);
}
return Res.mod(n);
}
M3)
ublic BigInteger Result3(BigInteger a , BigInteger b , BigInteger n){
if(b.equals(new BigInteger("0"))){
return new BigInteger("1");
}
else if(b.mod(new BigInteger("2")).equals(new BigInteger("0"))){
BigInteger Res = Result3(a,b.divide(new BigInteger("2")),n);
return (Res.multiply(Res)).mod(n);
}
else{
return ( (a.mod(n)).multiply(Result3(a, b.subtract(new BigInteger("1")), n)) ).mod(n);
}
}
M4)
public BigInteger Result4(BigInteger a , BigInteger b , BigInteger n){
BigInteger Res = new BigInteger("1");
while(!b.equals(new BigInteger("0"))) {
if(!(b.mod(new BigInteger("2"))).equals(new BigInteger("0"))) {
Res = Res.multiply(a).mod(n);
}
a = a.multiply(a).mod(n);
b = b.divide(new BigInteger("2"));
}
return Res;
}
答案 0 :(得分:1)
直接回答你的问题, 我认为BigInteger.modPow可能是你正在寻找的东西。
public BigInteger modPow(BigInteger exponent,
BigInteger m)
返回一个BigInteger,其值为(this ^ exponent mod m)
或者(并且更有效率),你也可以((mod n)获得(b mod n)幂,这应该使代码运行得更快。
(a ^ b mod n)=((mod n)^(b mod n)mod n)
答案 1 :(得分:0)
如果您不是非常需要表现,可以使用BigInteger
课程。 BigInteger
是不可变的。
public static BigInteger getValue(int a, int b, int n) {
return BigInteger.valueOf(a).modPow(BigInteger.valueOf(b), BigInteger.valueOf(n));
}
答案 2 :(得分:0)
慌张,这被搁置......
为了理论,如果你想编写自己的自定义方法,请根据数学技巧检查以下内容,以避免计算。首先是解决方案,然后是背后的数学。
您的子程序可能如下所示:
public static BigInteger customPowMod(BigInteger a, BigInteger b, BigInteger n){
BigInteger previous = a.mod(n);
BigInteger runningTotal = new BigInteger("1");
for(int i = 0; i < a.bitLength(); i++){
if(a.testBit(i)){
runningTotal = runningTotal.multiply(previous);
}
previous = previous.multiply(previous).mod(n);
}
return runningTotal.mod(n);
}
以下是如何调用该方法的示例:
public static void main(String[] args) {
BigInteger a = new BigInteger("1700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
BigInteger b = new BigInteger("6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
BigInteger n = new BigInteger("50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
//note the following produce the same values
System.out.println(customPowMod(a,b,n));
System.out.println(a.modPow(b,n));
}
现在解释
为了解释事情,我正在做较小的数字...这是手工过程,最后变成了代码。
a
= 17 b
= 63 n
= 5 首先您希望了解您的电源号b
由哪个base2供电。例如:
63 = 2 ^ 5 + 2 ^ 4 + 2 ^ 3 + 2 ^ 2 + 2 ^ 1 + 2 ^ 0 = 32 + 16 + 8 + 4 + 2 + 1.
OR二进制 11111
这可以通过从0迭代到我们的BigInteger b的.bitLength()
并用.testBit()
检查给定位来以编程方式找到。 因此Java代码中的for循环。
下一步我们会找到您的基本模数(n
)目标的倍数(您需要的值远远超过前一段的最高2):
让我们调用每个简化值a<power_of_2>
。
和手工值:
问题是这可以与找到base2权限的上一步同步完成,每次迭代你也会找到最新的a<power_of_2>
。 需要计算每个额外的方块,直到我们达到最大值,因此循环中的previous
值不断增加。
最后,我们将必要的值与彼此相加,然后是n
的模数。 这是在foor-loop的if语句中。
从上面的步骤我们得到了值并将它们加在一起(后跟循环结束时的模数):
1 * 1 * 1 * 1 * 4 * 2 %5 = 8%5 = 3