views:

418

answers:

8

I am trying to write a prime number function in C# and I am wondering if the follow code will work. It "appears" to work with the first 50 numbers or so. I just want to make sure it will work no matter how big the number is:

static bool IsPrime(int number)
{
    if ((number == 2) || (number == 3) || (number == 5) || (number == 7) || (number == 9))
            return true;

    if ((number % 2 != 0) && (number % 3 != 0) && (number % 5 != 0) &&
        (number % 7 != 0) && (number % 9 != 0) && (number % 4 != 0) &&
        (number % 6 != 0))
        return true;

        return false;
 }
+10  A: 

No it won't work! Try 121 = 11 * 11 for example which obviously isn't a prime.

For any number given to your function, that is a product of the prime numbers X1, X2, ..., Xn(where n >= 2) with all of them being greater or equal to 11, your function will return true. (And also, as already said, 9 isn't a prime).

From wikipedia you can see that:

In mathematics, a prime number (or a prime) is a natural number that has exactly two distinct natural number divisors: 1 and itself.

so a very simple and naive algorithm on checking whether a number is prime could be:

boolean isPrime(int number) {

    if (number == 1) return false;
    if (number == 2) return true;

    for (int i = 2; i < number; ++i)  {
       if (number % i = 0) return false;
    }

    return true;

}

For better algorithms check here: Primality Test

> "If it was so easy to check if a number was prime then I guess RSA wouldn't be so secure "Actually, RSA security depends on it being _easy_ to tell if a number is a prime (this makes secure key generation possible), and _hard_ for it to factor the product of two primes (this makes the encryption secure).
avalys
It's only necessary to test up to Math.sqrt(number)
Malfist
Thanks for your comment, you are right. I removed it.
@Malfist yes I know, it's enough! As I wrote it's a simple and naive algorithm.
and you can increment i by 2, once it's odd (so from 3) cause all even numbers (other than 2) are not primes
PostMan
Replace first two lines with `if ((number if (number < 9) return number > 1;` to properly handle 1 and negative numbers. And for the love of all that's holy, test only the odds up to the square root!
Charles
+2  A: 

This approach definitely won't work, unless your if statement explicitly enumerates all the prime numbers between 0 and sqrt(INT_MAX) (or the C# equivalent).

To properly check for primality, you basically need to attempt to divide your number by every prime number less than its square root. The Sieve of Eratosthenes algorithm is your best bet.

Drew Hall
int.MaxValue gives the C# max for an int.
Philip Smith
No, you only need to test up to the square root.
starblue
@starblue: For any particular number, you need to test up to its square root (as I said in my answer). For a general function to work for ALL possible inputs, it would have to encode all the primes up to the square root of its max possible input. Obviously if you were really going to write it this way (don't!!!), you'd need it to short circuit. Probably with a reversed switch statement with fall through if you were doing it in C. Better just to use an array of some kind though...
Drew Hall
If you extend the approach of the original poster to cover int you need to explicitly list the primes up to sqrt(INT_MAX).
starblue
@starblue: Exactly what I was trying to say... :)
Drew Hall
@starblue: Oh, whoops--now I see your point. I said 0 to INT_MAX, but meant 0 to sqrt(INT_MAX). Editing now...
Drew Hall
+1  A: 

You are apparently writing from a contrafactual dimension where 9 is a prime number, so I guess that our answers might not work for you. Two things though:

  1. Prime number generating functions are a non-trivial but exiting matter, the Wikipedia page is a good starter (http://en.wikipedia.org/wiki/Formula_for_primes)

  2. from (number%2!=0) it follows (number%4!=0). If you can't divide by 10, then you can't divide by 100 either.

Luther Blissett
A: 

Your function returns true for even numbers.

I highly doubt this will work for the general case. Primality testing is very involved.

hvgotcodes
Actually, it handles evens correctly. It returns true for 2, and false for all the other evens
Matthew Flaschen
my bad -- i actually put it into a unit test and ran some number through it, then misinterpreted my own results...
hvgotcodes
@hvgotcodes: Not really very involved--you just have to bootstrap up from 2.
Drew Hall
@Drew Hall, my test wasn't faulty, my reasoning upon seeing the test was faulty...
hvgotcodes
+3  A: 

It had to be done...

public static bool IsPrime(this int number)
{
    return (Enumerable.Range(1,number).Where(x => number % x == 0).Count() == 2);
}
fletcher
A: 

Primality testing is the way to go, but in case you want a quick and dirty hack, here's something.

If it's not working fast enough, you can build a class around it and store the PrimeNumbers collection from call to call, rather than repopulating it for each call.

    public bool IsPrime(int val)
    {
        Collection<int> PrimeNumbers = new Collection<int>();
        int CheckNumber = 5;
        bool divisible = true;
        PrimeNumbers.Add(2);
        PrimeNumbers.Add(3);

        // Populating the Prime Number Collection
        while (CheckNumber < val)
        {
            foreach (int i in PrimeNumbers)
            {
                if (CheckNumber % i == 0)
                {
                    divisible = false;
                    break;
                }
                if (i * i > CheckNumber) { break; }
            }
            if (divisible == true) { PrimeNumbers.Add(CheckNumber); }
            else { divisible = true; }
            CheckNumber += 2;
        }
        foreach (int i in PrimeNumbers)
        {
            if (CheckNumber % i == 0)
            {
                divisible = false;
                break;
            }
            if (i * i > CheckNumber) { break; }
        }
        if (divisible == true) { PrimeNumbers.Add(CheckNumber); }
        else { divisible = true; }

        // Use the Prime Number Collection to determine if val is prime
        foreach (int i in PrimeNumbers)
        {
            if (val % i == 0) { return false; }
            if (i * i > val) { return true; }
        }
        // Shouldn't ever get here, but needed to build properly.
        return true;
    }
T.K.
A: 

There are some basic rules you can follow to check if a number is prime

  1. Even numbers are out. If x % 2 = 0, then it is not prime
  2. All non-prime numbers have prime factors. Therefore, you only need test a number against primes to see if it factors
  3. The highest possible factor any number has is it's square root. You only need to check if values <= sqrt(number_to_check) are even divisible.

Using that set of logic, the following formula calculates 1,000,000 Primes Generated in: 134.4164416 secs in C# in a single thread.

    public IEnumerable<long> GetPrimes(int numberPrimes)
    {
      List<long> primes = new List<long> { 1, 2, 3 };
      long startTest = 3;

      while (primes.Count() < numberPrimes)
      {
        startTest += 2;
        bool prime = true;
        for (int pos = 2; pos < primes.Count() && primes[pos] <= Math.Sqrt(startTest); pos++)
        {
          if (startTest % primes[pos] == 0)
          {
            prime = false;
          }
        }
        if (prime)
          primes.Add(startTest);
      }
      return primes;
    }

Bear in mind, there is lots of room for optimization in the algorithm. For example, the algorithm could be parallelized. If you have a prime number (let's say 51), you can test all the numbers up to it's square (2601) for primeness in seperate threads as all it's possible prime factors are stored in the list.

thorkia
A: 
Syed Aiman Rais