2

如何使用 java 计算极大指数数的余数?例如。(48^26)/2401

我尝试使用 BIGITEGER,但是它为大除数提供了相同的输出。我不确定 BIG INTEGER 是否可以做到这一点。我已经尝试了所有其他 PRIMITIVE 数据类型。它们似乎还不够。

仅供参考,它尝试了以下代码:

BigInteger a = new BigInteger("48");
a = a.pow(26);
BigInteger b = new BigInteger("2401");//49*49
a = a.mod(b);
System.out.println(a);

我不知道为什么我每次都得到相同的输出,奇怪的是它现在工作正常。答案是 1128

4

7 回答 7

9

您可以使用较小数字的重复模数。

说你有

(a * b) % n
((A * n + AA) * (B * n + BB)) % n                     | AA = a %n & BB = b % n
(A * B * n^2 + A * N * BB + AA * B * n + AA * BB) % n
AA * BB % n                                           since x * n % n == 0
(a % n) * (b % n) % n

在你的情况下,你可以写

48^26 % 2401
(48^2) ^ 13 % 2401

作为

int n = 48;
for (int i = 1; i < 26; i++)
    n = (n * 48) % 2401;
System.out.println(n);

int n2 = 48 * 48;
for (int i = 1; i < 13; i++)
    n2 = (n2 * 48 * 48) % 2401;
System.out.println(n2);

System.out.println(BigInteger.valueOf(48).pow(26).mod(BigInteger.valueOf(2401)));

印刷

1128
1128
1128

正如@Ruchina 指出的那样,您的示例足够小,可以使用简单的双精度表达式进行计算。

for (int i = 1; i < 100; i++) {
    BigInteger mod = BigInteger.valueOf(48).pow(i).mod(BigInteger.valueOf(2401));
    double x = Math.pow(48, i) % 2401;
    if (mod.intValue() != x) {
        System.out.println(i + ": " + mod + " vs " + x);
        break;
    }
}

印刷

34: 736 vs 839.0

换句话说,任何 48 的幂都可以达到 33。

于 2013-07-12T14:03:27.913 回答
3

这对我有用。

import java.math.BigInteger;


public class BigMod{
        public static void main (String[] args){
                BigInteger b1 = new BigInteger ("48");
                BigInteger b2 = new BigInteger ("2401");
                BigInteger b3 = b1.pow(26);
                BigInteger result = b3.mod(b2);
                System.out.println(result);
        }
}

不确定您在使用 BigInteger 时遇到了什么问题。你能解释什么没用吗?

于 2013-07-12T14:06:56.527 回答
2

使用 BigInteger.modPow()。

BigInteger a = new BigInteger("48");
BigInteger b = new BigInteger("26");
BigInteger c = new BigInteger("2401");

BigInteger answer = a.modPow(b, c);

答案是 1128。请注意,BigInteger 是不可变的,因此对象 a、b 和 c 不能被修改。

于 2013-07-12T14:21:19.510 回答
2

您甚至不需要BigInteger为此,您可以使用 BigMod 分治算法利用以下mod操作属性来计算该值

(A * B) mod n = ((A mod n) * (B mod n)) mod n

那么(B ^ c) mod n可以看成是属性的一个特例:

(B ^ c) mod n = ((B mod n) * (B mod n) ... c times) mod n

以下代码进行计算:

public class BigModExample { 
    public static long bigMod(long  b, long  c, int n) {
        if (c == 0) {
            return 1;
        }

        // Returns: (b ^ c/2) mod n
        long b2 = bigMod(b, c / 2, n);        

        // Even exponent
        if ((c & 1) == 0) {
            // [((b ^ c/2) mod n) * ((b ^ c/2) mod n)] mod n
            return (b2 * b2) % n;
        } else {
            // Odd exponent
            // [(b mod n) * ((b ^ c/2) mod n) * ((b ^ c/2) mod n)] mod n
            return ((b % n) * (b2 * b2)) % n;
        }
    }

    public static void main(String... args) {
        System.out.println(bigMod(48, 26, 2401));
    }
}

印刷

1128
于 2013-07-12T14:23:18.113 回答
2

进一步解释彼得劳里的解决方案。

(a*b)%n
= ((A*n + AA) * (B*n + BB))%n where a=A*n+AA, AA=a%n & b=B*n+BB, BB=b%n
= (A*B*n^2 + A*n*BB + AA*B*n + AA*BB)%n
= (AA*BB)%n
= (a%n * b%n)%n

(a^c)%n
= (a^(c-1) * a)%n
= ((a^(c-1))%n * a%n)%n
= ((a^(c-2)*a)%n * a%n)%n
= ((a^(c-2)%n * a%n)%n * a%n)%n

示例 1:当 c 为 3 时

(a^3)%n
= ((a^2)*a)%n
= ((a^2)%n * a%n)%n
= ((a*a)%n * a%n)%n 
= ((a%n * a%n)%n * a%n)%n

示例 2:当 c 为 4 时

(a^4)%n
= ((a^3)*a)%n
= ((a^3)%n * a%n)%n
= ((a^2 * a)%n * a%n)%n
= (((a^2)%n * a%n)%n * a%n)%n
= (((a*a)%n * a%n)%n * a%n)%n
= ((a%n * a%n)%n * a%n)%n * a%n)%n

爪哇代码:

int a = 48;
int c = 26;
int n = 2401;
int a_mod_n = a%n;
int result = a_mod_n;
for (int i = 1; i < c; i++) {
    result = (result * a_mod_n) % n;
}
System.out.println("result: " + result);

48aa%nare一样模棱两可48。上面的 Java 代码严格遵循等式((a^(c-2)%n * a%n)%n * a%n)%n,以便于理解。

于 2014-04-13T10:54:41.077 回答
1
 BigDecimal b= BigDecimal.valueOf(Math.pow(48,26) %2401);

output b = 1128.0
于 2013-07-12T14:00:52.323 回答
0

尝试对大十进制数使用BigDecimal。它不容易出现错误doublefloat因为它的数据存储方式。此外,它有(可能)无限多的小数位。

于 2013-07-12T13:52:09.300 回答