简体   繁体   English

Java幂取幂法老是返回错误值

[英]Java power exponentiation method keeps returning wrong value

I am doing a small cryptography program and need a function to calculate power mod n我正在做一个小型密码学程序,需要一个 function 来计算功率 mod n

I wrote this method:我写了这个方法:

static int power(int x, int y, int p){
    int res = 1; // Initialize result
        
    x = x % p; // Update x if it is more than or equal to p
  
    while (y > 0) {
        res = ((res*x) % p)+p % p;
        y-=1;
    }
    return res;
}

But I have noticed it returns the wrong answer for certain cases.但我注意到它在某些情况下返回错误的答案。 Example:例子:

56295^779 mod 69997 should return 53580 but returns 20366 instead 56295^779 mod 69997 应该返回 53580 但返回 20366

43576^7116 mod 50087 should return 35712 but returns 40613 instead 43576^7116 mod 50087 应该返回 35712 但返回 40613

It doesnt always return a wrong answer, so I am not sure why exactly this is happening.它并不总是返回错误的答案,所以我不确定为什么会发生这种情况。 Any advice?有什么建议吗?

You are the victim of integer overflow.您是 integer 溢出的受害者。

        res = ((res*x) % p)+p % p;

This line could overflow.这条线可能会溢出。 res * x is not guaranteed to fit into a signed 32-bit integer (but does fit into a signed 64-bit integer). res * x 不能保证适合带符号的 32 位 integer(但确实适合带符号的 64 位整数)。

Examples:例子:

2147483647 * 2 = -2
1147483647 * 22 = -525163542

To prevent this from happening, you can make res a long instead of int , and then cast back to int when returning from the function.为防止这种情况发生,您可以将 res 设为long而不是int ,然后在从 function 返回时将其转换回int

static int power(int x, int y, int p){
    long res = 1; // Initialize as long to prevent overflow!
        
    x = x % p;
  
    while (y > 0) {
        res = ((res*x) % p)+p % p; // No more overflow here!
        y-=1;
    }
    return (int) res; // Cast result back to int
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM