0

I'm try to see if large numbers are prime or not, number whose length are 11. Here is the code I am using:

private static boolean isPrime(BigInteger eval_number){

        for(int i=2;i < eval_number.intValue();i++) {
            if(eval_number.intValue() % i==0)
                return false;
        }
        return true;

    }

Now the number I'm inspecting in the debugger is eval_number which equals 11235813213. However when I inspect the eval_number.intValue() in the debugger instead of the value being 11235813213 the value is -1649088675. How is this happening? Also what would be a better way in inspecting large numbers to see if they are prime?

M A
  • 71,713
  • 13
  • 134
  • 174
user481610
  • 3,230
  • 4
  • 54
  • 101
  • 2
    "How is this happening?" It's called an overflow. When the variable type only stores x bytes and you need y bytes to store the value you want, where y > x. – Fabio Aug 08 '15 at 12:07
  • 1
    I don't know java, but the problem might be with intValue, since it returns an int and usually ints have low maximum value – Fabio Aug 08 '15 at 12:09
  • that's a very bad way to check for prime – phuclv Aug 08 '15 at 12:29
  • LưuVĩnhPhúc what would be a better way? – user481610 Aug 08 '15 at 12:41
  • limit the upper bound to `sqrt(eval_number)` and only check for divisibility of numbers of the form `6k ± 1` http://stackoverflow.com/a/1801446/995714 http://stackoverflow.com/q/453793/995714 – phuclv Aug 08 '15 at 13:46

6 Answers6

3

The strange value is a result of an overflow. The number held by the BigInteger instance is greater than 2^31-1 (Integer.MAX_VALUE) thus it can't be represented by an int. For the primcheck: BigInteger provides isProbablePrime(int) and there are several other fast (more or less) algorithms that allow to check whether a number is a primnumber with a given failure-rate. If you prefer 100% certainty you can optimize your code by reducing the upper-bounds for numbers to check to sqrt(input) and increasing the step-size by two. Or generate a prim-table, if the algorithm is used several times.

2

intValue() returns an integer equivalent for the given BigInteger number.

Since you are passing the value 11235813213, which is much larger than Integer.MAX_VALUE(maximum possible value for an int variable), which is 2147483647. So , it resulted in overflowing of the integer.

Also what would be a better way in inspecting large numbers to see if they are prime?

You should use only BigInteger numbers for finding out large primes. Also, check this question (Determining if a BigInteger is Prime in Java) which I asked a year ago.

Community
  • 1
  • 1
Am_I_Helpful
  • 18,735
  • 7
  • 49
  • 73
2

As others have said the number you are checking is ouside of the range of int.
You could use a long, but that only delays the problem, it will still fail on numbers beyond long's range.
The solution is to use BigInteger arithmetic :

private static boolean isPrime(BigInteger eval_number) {
    for (BigInteger i = BigInteger.valueOf(2); i.compareTo(eval_number) < 0; i = i.add(BigInteger.ONE)) {
        if (eval_number.mod(i).equals(BigInteger.ZERO)) {
            return false;
        }
    }
    return true;
}

That is just a correction of the inmediate problem your question is about. There are still things to improve there. Checking for being prime can be made more efficient. You don't have to check even numbers except 2 and you only need to check till the square root of the number in question.

Anonymous Coward
  • 3,140
  • 22
  • 39
1

You convert BigInteger to 32bit integer. If it is bigger than 2^31, it will return incorrect value. You need to do all the operations over BigInteger instances. I assume that you use BigInteger because of long being insufficient for other cases, but for number you stated as an example would be use of long instead of int sufficient. (long will be enough for numbers up to 2^63).

Vojtěch Kaiser
  • 568
  • 3
  • 15
0

You have to make all operations with BigInteger, without converting it to int :

private static boolean isPrime(BigInteger eval_number) {
    for (BigInteger i = BigInteger.valueOf(2); i.compareTo(eval_number) < 0; i = i.add(BigInteger.ONE)) {
        if (eval_number.divideAndRemainder(i)[1].equals(BigInteger.ZERO)) {
            System.out.println(i);
            return false;
        }

    }
    return true;
} 
ka4eli
  • 5,294
  • 3
  • 23
  • 43
0

If you want to check whether a BigInteger is Prime or not you can use java.math.BigInteger.isProbablePrime(int certainty) it will returns true if this BigInteger is probably prime, false if it's definitely composite. If certainty is ≤ 0, true is returned.

Rohit Poudel
  • 1,793
  • 2
  • 20
  • 24