1

I am trying to find the next prime number after the number the user enters in.

Here is the code I have so far:

public int Calculation(int number)
{
    //set the isPrime to false
    bool isPrime = false;

    //do this while isPrime is still false
    do
    {
        //increment the number by 1 each time
        number = number + 1;

        int squaredNumber = (int)Math.Sqrt(number);

        //start at 2 and increment by 1 until it gets to the squared number
        for (int i = 2; i <= squaredNumber; i++)
        {
            //how do I check all i's?
            if (number % i != 0)
            {
                isPrime = true;
            }


        }


    } while (isPrime == false);

    //return the prime number
    return number;
}

I know something is missing because the first time i gives a remainder that is NOT 0 then it returns that number as prime. The problem is I can't figure out the logic/syntax to see if every i in that loop is NOT 0 as remainder.

Dmitry
  • 13,797
  • 6
  • 32
  • 48
mortey
  • 179
  • 1
  • 4
  • 15
  • I think you're check for primality is wrong, if `number % i == 0` then `i` is a divisor so the number is not prime. – ioseph May 14 '14 at 02:08
  • What is the " **next** prime number"? You mean, smallest prime number which is greater than the number inputted by user? –  May 14 '14 at 02:08
  • yes. So if they type 5 then it returns 7. If they type 7 then it returns 11 for example. – mortey May 14 '14 at 02:13

3 Answers3

6

There are better ways to find prime numbers, but keeping in line with your algorithm, what you want to do is start with isPrime = true;, then set it to false if there are any i where the remainder is 0. You can also break out of the loop at that point.

So a revised version:

public int Calculation(int number)
{    
    while(true)
    {
        bool isPrime = true;
        //increment the number by 1 each time
        number = number + 1;

        int squaredNumber = (int)Math.Sqrt(number);

        //start at 2 and increment by 1 until it gets to the squared number
        for (int i = 2; i <= squaredNumber; i++)
        {
            //how do I check all i's?
            if (number % i == 0)
            {
                isPrime = false;
                break;
            }
        }
        if(isPrime)
            return number;
    }
}
Ben Aaronson
  • 6,955
  • 2
  • 23
  • 38
  • His variable is just named badly – Liam McInroy May 14 '14 at 02:13
  • 1
    I think he his square rooting it, right? He's calling it `squaredNumber`, but it's a `Sqrt` operation. – tmoore82 May 14 '14 at 02:13
  • 1
    I deleted my answer because they were the same and you were first, but as a sidenote, just casting as an `int` will not round perfectly, see http://stackoverflow.com/questions/4181942/convert-double-to-int, I would use a different method for rounding up as is the algorithm. Also you want to start at `number` not 2 as @elgonzo pointed out – Liam McInroy May 14 '14 at 02:23
  • Thanks! Yours makes the most sense to me. I apologize for the stupid question (hence the downvotes I guess). Only been programming for a month and got stumped. The key to it I suppose was remembering that break got out of only the "if" statement not the whole for loop. That way it could continue through the loop – mortey May 14 '14 at 02:25
  • 1
    @OutlawLemur Yep, these are both good points. I'm not improving the algorithm beyond what was causing the actual problem asked about because with prime number generation it'd hard to know when to stop improving! But these are good points for the OP to keep in mind – Ben Aaronson May 14 '14 at 02:26
3

If you use a BitArray as a Sieve of Eratosthenes you won't need a loop to test for prime. The value of the BitArray at that index will be true or false according to whether it's prime.

A function like this will produce the Bitarray:

public static BitArray ESieve(int upperLimit)
{
    int sieveBound = (int)(upperLimit - 1);
    int upperSqrt = (int)Math.Sqrt(sieveBound);
    BitArray PrimeBits = new BitArray(sieveBound + 1, true);
    PrimeBits[0] = false;
    PrimeBits[1] = false;
    for(int j = 4; j <= sieveBound; j += 2)
    {
        PrimeBits[j] = false;
    }
    for(int i = 3; i <= upperSqrt; i += 2)
    {
        if(PrimeBits[i])
        {
            int inc = i * 2;
            for(int j = i * i; j <= sieveBound; j += inc)
            {
                PrimeBits[j] = false;                       
            }
        }
    }
    return PrimeBits;
}

Declare the Bitarray:

BitArray IsPrime = ESieve(1000000);

Finding the next prime is a simple matter of iterating through the bitarray to find the next one set to true:

int FindNextPrime(int number)
{
    number++;
    for(; number < IsPrime.Length; number++)
        //found a prime return that number
        if(IsPrime[number])
            return number;
    //no prime return error code
    return -1;
}
tinstaafl
  • 6,908
  • 2
  • 15
  • 22
-3
if ((number % i) != 0)
{
    isPrime = true;
}

You need to wrap number % i in parens due to % having lower operator precedence to !=. I didn't test the correctness of the rest of your logic, but an input of 5 correctly returns 7 as the next prime.

Jeff Dunlop
  • 893
  • 1
  • 7
  • 20