0

I need to calculate this: 2894135^3787313 mod 4028033

As you can see below i tried to use the BigInteger because i have really huge numbers.

import java.lang.Math;
import java.util.Scanner;
public class BigInteger extends Number implements Comparable<BigInteger>
{
  public static void main(String[] args)
  {
  BigInteger result=new BigInteger(Math.pow(2894135,3787313) % 4028033);
    System.out.println(result);
  }
}

Error:

/tmp/java_Wcf144/BigInteger.java:19: error: BigInteger is not abstract and does not override abstract method doubleValue() in Number public class BigInteger extends Number implements Comparable ^ /tmp/java_Wcf144/BigInteger.java:24: error: constructor BigInteger in class BigInteger cannot be applied to given types;
BigInteger result=new BigInteger(Math.pow(2894135,3787313) % 4028033); ^ required: no arguments found: double reason: actual and formal argument lists differ in length 2 errors

Thomas
  • 45
  • 7
  • 5
    rename your class to something else other than `BigInteger` – Reimeus Apr 25 '17 at 10:57
  • 3
    Aside from anything else, you're trying to do all the arithmetic *first*, and then convert the *result* to `BigInteger`. That isn't going to work. You should be doing *all the arithmetic* in `BigInteger`. And yes, as Reimeus says, you really don't want to be declaring your own class as `BigInteger`... – Jon Skeet Apr 25 '17 at 10:58
  • But *don't* rename it to Biginteger (as in your title). – Steve Smith Apr 25 '17 at 10:59
  • Not sure if you realize this, but `2894135 ^ 3787313` is a _really_ **big** number. Basically, you cannot calculate that expression. Even `BigInteger` won't help you here... – radoh Apr 25 '17 at 11:01
  • no chance for calculating that? I mean wolframalpha can do it, but i need to run this calculation with 3000 different numbers. I will read the numbers from a txt file – Thomas Apr 25 '17 at 11:03
  • Wolfram will do an approximation to a certain number of digits. It won't calculate all 25 million digits... – radoh Apr 25 '17 at 11:07
  • Still, "funny" question. And it taught me an important lesson: "even when you are in a hurry to answer; read the question carefully; and check all its details." – GhostCat Apr 25 '17 at 11:11
  • Ah nice, I didn't know about `modPow()`. Because if you'd first try to calculate `2894135 ^ 3787313` and then do the modulo, you'd be in trouble... – radoh Apr 25 '17 at 11:13
  • @radoh: calculating that number is not extremely slow. Turning it into a string is (turning a 2 million digit value into a string took a few minutes in my highly optimized Delphi BigInteger implementation, calculating it only a few seconds). But using modPow() instead of pow() will make both calculating and displaying a ***lot*** faster. And BigIntegers can easily handle 25 million digits. – Rudy Velthuis Apr 26 '17 at 21:40
  • @RudyVelthuis hmm, I stand corrected. It took ~30 seconds to calculate it on my machine, which is much less than I would've anticipated. To be honest, at first I expected the number to have a lot more digits (even though 25mil is a lot already). – radoh Apr 27 '17 at 07:50
  • @radoh: Try to do a `.toString()` on it. I guess you'll have time to make and drink a cup of coffee (or two) before it is finished. Don't print it, though! – Rudy Velthuis Apr 27 '17 at 09:39

4 Answers4

6

You will get wrong answer even after solving the errors because Math.pow(2894135,3787313), This will cause overflow in double and it will return largest possible value of double Double.MAX_VALUE.

So you need to do all operations after converting them into BigInteger.

import java.lang.Math;
import java.util.Scanner;
import java.math.BigInteger;
public class Main
{
  public static void main(String[] args)
  {
        BigInteger a=BigInteger.valueOf(2894135);
        BigInteger b=BigInteger.valueOf(3787313);
        BigInteger m=BigInteger.valueOf(4028033);
        BigInteger result=a.modPow(b,m); //calculates a^b %m
        System.out.println(result);
  }
}

EDIT: If you want to do this in more optimized way then you can use concept of Modular Exponentiation. This will give output in O(log(exponent)) complexity. Here you can't use bigger values because it may cause overflow in long which ends up in giving wrong result.

Code:

public class Main
{
  public static void main(String[] args)
  {
        long a=2894135;
        long b=3787313;
        long m=4028033;

        long result=modularExponentiation(a,b,m);
        System.out.println(result);
  }

    static long modularExponentiation(long a,long b,long m)
    {
        long result=1;
        while(b>0)
        {
            if(b % 2 ==1)
                result=(result * a)%m;
            a=(a*a)%m;
            b=b/2;
        }
        return result;
    }
}
Sanket Makani
  • 2,491
  • 2
  • 15
  • 23
  • this! Thank you very much for your time, i got the the correct result :) – Thomas Apr 25 '17 at 11:10
  • Although you came in a bit later; you where the first one to give the fully correct answer. My upvote for that! – GhostCat Apr 25 '17 at 11:12
  • AFAIK, modular exponentiation is what `BigInteger.modPow` uses too. But of course for BigIntegers, not for longs. – Rudy Velthuis Apr 25 '17 at 16:06
  • Ahh @RudyVelthuis , I didn't know that `BigInteger.modPow` uses `modular exponentiation`. Thanks for informing me. P.S: Though that thought came in my mind while writing the answer that It should be using it. :P – Sanket Makani Apr 25 '17 at 16:20
3

You have not implemented doubleValue() method in your class. And you also need to rename your main class with some other name , Big Integer is a seperate object.

Dishonered
  • 8,449
  • 9
  • 37
  • 50
2

Two issues: the first one about the mis-use of the BigInteger class.

you declared your own BigInteger class, which sorry doesn't make much sense. If you want to be able to work with arbitrary sized Integer values; use the existing java.math.BigInteger class.

From there:

BigInteger result=new BigInteger(Math.pow(2894135,3787313) % 4028033);

You are not computing with BigInteger objects.

You are using int literals, to compute a value; and the result of that you intend to use as ctor argument for creating a single BigInteger.

You could go for:

BigInteger op1 = new BigInteger(2894135)
BigInteger op2 = new BigInteger(3787313);
BigInteger op3 = new BigInteger(4028033);
BigInteger result = op1.modpow(op2, op3); 

instead. Depending on the numbers you intend to use; you might or might not be able to do the "pow" calculation as you did before; using Math.pow() and work on double literals. But the above will work for any numbers that fitting into the JVM.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • also the constructor `BigInter(long/double)` isn't working. use `BigInteger.valueOf((long)Math.pow(2894135,3787313))` – XtremeBaumer Apr 25 '17 at 11:04
  • It's true, but this is not what the error is about. – Ivar Apr 25 '17 at 11:07
  • Thank you for the help! The code from Sanket Makani below solved all my problem and did this huge calculation! – Thomas Apr 25 '17 at 11:09
  • Well the real real initial problem is as @Sushobh Nadiger noted. He is extending the `Number` class. That class has an abstract function `doubleValue()` which the OP's class first needs to override before it can compile. – Ivar Apr 25 '17 at 11:13
1

Why do you even want to create a BigInteger class.

BigInteger is already defined in Java, use it

https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html

Also, do all the operations on BigInteger, rather than converting them to BigInteger at the end.

Abhi

Abhi
  • 55
  • 1
  • 10