Check if number is prime number
Asked Answered
G

32

70

I would just like to ask if this is a correct way of checking if number is prime or not? because I read that 0 and 1 are NOT a prime number.

int num1;

Console.WriteLine("Accept number:");
num1 = Convert.ToInt32(Console.ReadLine());
if (num1 == 0 || num1 == 1)
{
    Console.WriteLine(num1 + " is not prime number");
    Console.ReadLine();
}
else
{
    for (int a = 2; a <= num1 / 2; a++)
    {
        if (num1 % a == 0)
        {
            Console.WriteLine(num1 + " is not prime number");
            return;
        }

    }
    Console.WriteLine(num1 + " is a prime number");
    Console.ReadLine();
}
Guerrero answered 1/4, 2013 at 12:7 Comment(7)
Yes, a prime number is defined to be greater than one.Optimist
would just like to ask if this is a correct way of checking - yes. Maybe you wanted to ask if it is a efficient way of checking?Ponton
so is it efficient then??Guerrero
Nope. Trivially, you can start a at 3 and increment it by 2 instead of 1 (and handle 2 being prime as a special case). But see here: en.wikipedia.org/wiki/Sieve_of_EratosthenesOptimist
@MatthewWatson A sieve is good if one wants to generate all the primes up to some limit, but to check whether one number is prime, it's useless.Vanvanadate
@DanielFischer It's certainly not useless, it just might be inefficient, depending on the number. If the number is sufficiently small it's not even going to be inefficient.Flail
@Flail What do you mean with "If it's sufficiently small it's not even going to be inefficient"? If you sieve up to sqrt(n) to get the primes you need for trial division, the sieving is more work than the unnecessary divisions by composites, if you avoid multiples of 2, 3, and maybe 5, if you're enterprisy. If you're sieving to n to look up whether n is prime in the sieve, you have an asymptotically worse algorithm (and the constant factors don't let it win for small numbers either).Vanvanadate
S
128
var number;

Console.WriteLine("Accept number:");
number = Convert.ToInt32(Console.ReadLine());

if (IsPrime(number))
{
    Console.WriteLine("It is prime");
}
else
{
    Console.WriteLine("It is not prime");
}       

public static bool IsPrime(int number)
{
    if (number <= 1) return false;
    if (number == 2) return true;
    if (number % 2 == 0) return false;

    var boundary = (int)Math.Floor(Math.Sqrt(number));
          
    for (int i = 3; i <= boundary; i += 2)
        if (number % i == 0)
            return false;
    
    return true;        
}

I changed number / 2 to Math.Sqrt(number) because from in wikipedia, they said:

This routine consists of dividing n by each integer m that is greater than 1 and less than or equal to the square root of n. If the result of any of these divisions is an integer, then n is not a prime, otherwise it is a prime. Indeed, if n = a*b is composite (with a and b ≠

  1. then one of the factors a or b is necessarily at most square root of n
Saleme answered 1/4, 2013 at 12:10 Comment(25)
Good solution. Note though that you are recalculating the square root every time through the loop.Frans
Also, why the ceiling instead of the floor?Frans
@EricLippert recalculating has done. Thanks! Ceiling isn't right? For 35, the boundary shouldn't be 6 ?Gemperle
Why would you need to go to six for 35? You've already determined that it is not a prime when you checked five.Frans
Consider three cases. If the number is actually prime then it doesn't matter when you stop at the ceiling or the floor; either way you are going to deduce correctly that it is prime. Now suppose that it is composite and a perfect square. Then the ceiling and the floor are equal, so again, it doesn't matter which you choose because they are the same. Now suppose that it is composite and not a perfect square. Then it has a factor that is less than its square root, so the floor is correct. No matter which of these three cases we're in, you can take the floor.Frans
Note that this argument requires that my second claim is true: that for every perfect square, the ceiling and floor of the square root are equal. If Math.Sqrt ever says that the square root of 10000 is 99.9999999999999 instead of 100.0000000000000, my claim is wrong and you should use the ceiling. Are there any cases where my claim is wrong?Frans
So lets think about other ways that your algorithm is inefficient. Suppose you are checking a large prime. You check to see if it is divisible by 2 first. It isn't. Then you check 3. It isn't. Then you check 4. Why are you checking 4? If it is divisible by 4 then it must have already been divisible by 2. You then check 5. Then 6. Again, why check 6? It can only be divisible by 6 if it is divisible by 2 and 3, which you've already checked.Frans
@EricLippert Hmm, I supposed you are totally right about floor issue. Updated my answer. Thanks!Gemperle
@EricLippert Are there any cases where my claim is wrong? Well, since Math.Sqrt() takes double as a parameter and returns double (in this case), I don't think so it can return like 99.9999999999999. But since if you asked it, I can't be sure! Sound might be a good question for StackOverflow.Gemperle
@EricLippert You are totally right on third section also. So, the most efficient way seems like; checking all prime numbers to Math.Floor(Math.Sqrt(number)) ?Gemperle
That is correct. However, that presupposes that you know what all the primes are up to the root; since you wouldn't be asking the question "is this prime?" in the first place if you knew what all the primes were, you might not know the primes up to the root. So one way to speed it up without knowing all the primes up to the root is to try 2, try 3, and then try 5, 7, 9, 11, 13, 15, 17... and not care about the fact that you didn't need to try 9 or 15. You've already halved the work.Frans
@SonerGönül That depends. If you test one number, finding the primes to the square root is much more work than simply doing trial division omitting even numbers (except 2) and multiples of 3 (except 3 itself). If you test a lot of numbers, getting the primes for the trial divisions absolutely is worth it.Vanvanadate
You can do even less work by observing that all primes other than 2 and 3 leave a remainder of either 1 or 5 when divided by 6. (Do you see why?) So after checking 2, 3 and 5, you can check 6 + 1, 6 + 5, 12 + 1, 12 + 5, 18 + 1, 18 + 5, 24 + 1, 24 + 5, ... and again, not care that checking 24 + 1 is unnecessary because you already checked 5. This way you can eliminate two thirds of the factors automatically.Frans
Wow.. We are going more deep! So @EricLippert we can use recursive method to find them as more efficient? But in big numbers, that might be a problem but small numbers that might be very efficient. Also what is the pattern of 6 + 1, 6 + 5, 12 + 1, 12 + 5, 18 + 1, 18 + 5, 24 + 1, 24 + 5 ? Multiple nearest prime numbers + 1 ?Gemperle
@SonerGönül Let the remainder of n when divided by 6 be r. If r is one of 0, 2, 4, then n is divisible by 2 (and vice versa). If r is one of 0, 3, then n is divisible by 3 (and vice versa). That leaves the remainders 1 and 5 for the numbers that have a chance of being a prime > 3.Vanvanadate
The pattern is one-times-six + 1, one-times-six + 5, two-times-six + 1, two-times-six + 5, ...Frans
So your loop can be int i = 6; while (i < boundary) { check if i + 1 divides the number; Check if i + 5 divides the number; i = i + 6}, and you only check two numbers in every six.Frans
@EricLippert, so I understand the algorithm where I have a set of numbers, say 1-10000, and I can start at two, and then eliminate all numbers, by twos, to the end. I can do the same for three. And that eliminates a large portion of the list very quickly. If in the process my number is one of those eliminated, then it's not prime because it's divisible by two or three. But I don't understand how I can jump by sixes(+1/5) and not have to check any other numbers at all. Can you help me grasp this?Palmore
@EricLippert OMG, how did I forget to update this question? Eric, please feel free to update my answer..Gemperle
I am a bit late to the party, but, this doesn't compile. Floor result in a double, and needs a explicit cast. However, casting from double to int already floors the double, so you can just use int boundary = (int)Math.Sqrt(number);.Delectable
@SonerGönül: Returning to this old question -- I checked all the square ints and they all have the property that i == (int)Floor(Sqrt(i * i)). I also checked all the square longs that are less than 2<sup>54</sup> and they're fine too. I haven't checked the square longs between 2<sup>54</sup> and 2<sup>63</sup>.Frans
@EricLippert: Aren't all these empirical checks specific to the .NET implementation? What if the .NET implementation is different? Is it possible instead to find a specification that clearly states what we are looking for?Once
@EricLippert: I found this answer that states: "In IEEE 754 floating-point, if the double-precision value x is the square of a nonnegative representable number y (i.e. yy == x and the computation of yy does not involve any rounding, overflow, or underflow), then sqrt(x) will return y." Is this applicable to .NET?Once
to skip even numbers (and up to x2 performance gain) add if (nbr % 2 == 0) return false; and change the for loop to for (int i = 3; i <= boundary; i += 2) (Due to my reputation, I can't edit the answer)Bouse
Since you're only dealing with positive numbes, can't you just skip Math.Floor in (int)Math.Floor(Math.Sqrt(number)), as casting to int already rounds down?Trust
R
21

Using Soner's routine, but with a slight variation: we will run until i equals Math.Ceiling(Math.Sqrt(number)) that is the trick for the naive solution:

boolean isPrime(int number)
{
    if (number == 1) return false;
    if (number == 2) return true;

    var limit = Math.Ceiling(Math.Sqrt(number)); //hoisting the loop limit

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

}
Rascally answered 1/4, 2013 at 12:11 Comment(2)
Calculating square root each time in the loop? Isn't it inefficient?Smokedry
What @Smokedry meant is that the for loop recalculates the Sqrt each time around testing each possible divisor - apparently optimization won't hoist the constant expression out since it can't know what Math.Ceiling or Math.Sqrt compute (imagine if it was (new Random()).Next(number)) so you should be hoisting it out.Bashemath
T
13

Here's a nice way of doing that.

    static bool IsPrime(int n)
    {
        if (n > 1)
        {
            return Enumerable.Range(1, n).Where(x => n%x == 0)
                             .SequenceEqual(new[] {1, n});
        }

        return false;
    }

And a quick way of writing your program will be:

        for (;;)
        {
            Console.Write("Accept number: ");
            int n = int.Parse(Console.ReadLine());
            if (IsPrime(n))
            {
                Console.WriteLine("{0} is a prime number",n);
            }
            else
            {
                Console.WriteLine("{0} is not a prime number",n);
            }
        }
Thigmotropism answered 17/1, 2014 at 2:40 Comment(6)
3 years after, do you still write code like for(;;) ?Archibaldo
If you have a large number that requires a long, this doesn't appear to work since Enumerable.Range doesn't have an overload for long. In addition, you're consuming a lot of memory and allocation time to create a list of all numbers between 1 and n. Finally, you don't need to check every value since all even numbers are known to be not prime (i.e. divisible by 2).Farthermost
After having given that criticism, I will say that I like the succinctness of your solution.Farthermost
I disagree with @MattRuwe 's comment about "create a list of all numbers between ...". AFAIK, Range, Where, & SequenceEqual work by streaming the sequence without storing any element except the last read one.Mertz
Interesting - I didn't know that about Range, Where and SequenceEqual.Farthermost
@Dementic LOL no.Thigmotropism
I
9

This is basically an implementation of a brilliant suggestion made by Eric Lippert somewhere above.

    public static bool isPrime(int number)
    {
        if (number <= 1) return false;
        if (number == 2 || number == 3 || number == 5) return true;
        if (number % 2 == 0 || number % 3 == 0 || number % 5 == 0) return false;

        var boundary = (int)Math.Floor(Math.Sqrt(number));

        // You can do less work by observing that at this point, all primes 
        // other than 2 and 3 leave a remainder of either 1 or 5 when divided by 6. 
        // The other possible remainders have been taken care of.
        int i = 6; // start from 6, since others below have been handled.
        while (i <= boundary)
        {
            if (number % (i + 1) == 0 || number % (i + 5) == 0)
                return false;

            i += 6;
        }

        return true;
    }
Ideo answered 26/5, 2017 at 13:56 Comment(3)
Why not change the loop to for (int i = 6; i <= boundary; i += 6)Gladdy
Might change the first line to if (number <= 1) return false;Gladdy
@Gladdy You don't use the FOR loop, because inside, until that return false; it's incrementing 1 by 1, and not by 6. This is probably the best code in this page.Mieshamiett
W
7

I've implemented a different method to check for primes because:

  • Most of these solutions keep iterating through the same multiple unnecessarily (for example, they check 5, 10, and then 15, something that a single % by 5 will test for).
  • A % by 2 will handle all even numbers (all integers ending in 0, 2, 4, 6, or 8).
  • A % by 5 will handle all multiples of 5 (all integers ending in 5).
  • What's left is to test for even divisions by integers ending in 1, 3, 7, or 9. But the beauty is that we can increment by 10 at a time, instead of going up by 2, and I will demonstrate a solution that is threaded out.
  • The other algorithms are not threaded out, so they don't take advantage of your cores as much as I would have hoped.
  • I also needed support for really large primes, so I needed to use the BigInteger data-type instead of int, long, etc.

Here is my implementation:

public static BigInteger IntegerSquareRoot(BigInteger value)
{
    if (value > 0)
    {
        int bitLength = value.ToByteArray().Length * 8;
        BigInteger root = BigInteger.One << (bitLength / 2);
        while (!IsSquareRoot(value, root))
        {
            root += value / root;
            root /= 2;
        }
        return root;
    }
    else return 0;
}

private static Boolean IsSquareRoot(BigInteger n, BigInteger root)
{
    BigInteger lowerBound = root * root;
    BigInteger upperBound = (root + 1) * (root + 1);
    return (n >= lowerBound && n < upperBound);
}

static bool IsPrime(BigInteger value)
{
    Console.WriteLine("Checking if {0} is a prime number.", value);
    if (value < 3)
    {
        if (value == 2)
        {
            Console.WriteLine("{0} is a prime number.", value);
            return true;
        }
        else
        {
            Console.WriteLine("{0} is not a prime number because it is below 2.", value);
            return false;
        }
    }
    else
    {
        if (value % 2 == 0)
        {
            Console.WriteLine("{0} is not a prime number because it is divisible by 2.", value);
            return false;
        }
        else if (value == 5)
        {
            Console.WriteLine("{0} is a prime number.", value);
            return true;
        }
        else if (value % 5 == 0)
        {
            Console.WriteLine("{0} is not a prime number because it is divisible by 5.", value);
            return false;
        }
        else
        {
            // The only way this number is a prime number at this point is if it is divisible by numbers ending with 1, 3, 7, and 9.
            AutoResetEvent success = new AutoResetEvent(false);
            AutoResetEvent failure = new AutoResetEvent(false);
            AutoResetEvent onesSucceeded = new AutoResetEvent(false);
            AutoResetEvent threesSucceeded = new AutoResetEvent(false);
            AutoResetEvent sevensSucceeded = new AutoResetEvent(false);
            AutoResetEvent ninesSucceeded = new AutoResetEvent(false);
            BigInteger squareRootedValue = IntegerSquareRoot(value);
            Thread ones = new Thread(() =>
            {
                for (BigInteger i = 11; i <= squareRootedValue; i += 10)
                {
                    if (value % i == 0)
                    {
                        Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                        failure.Set();
                    }
                }
                onesSucceeded.Set();
            });
            ones.Start();
            Thread threes = new Thread(() =>
            {
                for (BigInteger i = 3; i <= squareRootedValue; i += 10)
                {
                    if (value % i == 0)
                    {
                        Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                        failure.Set();
                    }
                }
                threesSucceeded.Set();
            });
            threes.Start();
            Thread sevens = new Thread(() =>
            {
                for (BigInteger i = 7; i <= squareRootedValue; i += 10)
                {
                    if (value % i == 0)
                    {
                        Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                        failure.Set();
                    }
                }
                sevensSucceeded.Set();
            });
            sevens.Start();
            Thread nines = new Thread(() =>
            {
                for (BigInteger i = 9; i <= squareRootedValue; i += 10)
                {
                    if (value % i == 0)
                    {
                        Console.WriteLine("{0} is not a prime number because it is divisible by {1}.", value, i);
                        failure.Set();
                    }
                }
                ninesSucceeded.Set();
            });
            nines.Start();
            Thread successWaiter = new Thread(() =>
            {
                AutoResetEvent.WaitAll(new WaitHandle[] { onesSucceeded, threesSucceeded, sevensSucceeded, ninesSucceeded });
                success.Set();
            });
            successWaiter.Start();
            int result = AutoResetEvent.WaitAny(new WaitHandle[] { success, failure });
            try
            {
                successWaiter.Abort();
            }
            catch { }
            try
            {
                ones.Abort();
            }
            catch { }
            try
            {
                threes.Abort();
            }
            catch { }
            try
            {
                sevens.Abort();
            }
            catch { }
            try
            {
                nines.Abort();
            }
            catch { }
            if (result == 1)
            {
                return false;
            }
            else
            {
                Console.WriteLine("{0} is a prime number.", value);
                return true;
            }
        }
    }
}

Update: If you want to implement a solution with trial division more rapidly, you might consider having a cache of prime numbers. A number is only prime if it is not divisible by other prime numbers that are up to the value of its square root. Other than that, you might consider using the probabilistic version of the Miller-Rabin primality test to check for a number's primality if you are dealing with large enough values (taken from Rosetta Code in case the site ever goes down):

// Miller-Rabin primality test as an extension method on the BigInteger type.
// Based on the Ruby implementation on this page.
public static class BigIntegerExtensions
{
  public static bool IsProbablePrime(this BigInteger source, int certainty)
  {
    if(source == 2 || source == 3)
      return true;
    if(source < 2 || source % 2 == 0)
      return false;

    BigInteger d = source - 1;
    int s = 0;

    while(d % 2 == 0)
    {
      d /= 2;
      s += 1;
    }

    // There is no built-in method for generating random BigInteger values.
    // Instead, random BigIntegers are constructed from randomly generated
    // byte arrays of the same length as the source.
    RandomNumberGenerator rng = RandomNumberGenerator.Create();
    byte[] bytes = new byte[source.ToByteArray().LongLength];
    BigInteger a;

    for(int i = 0; i < certainty; i++)
    {
      do
      {
        // This may raise an exception in Mono 2.10.8 and earlier.
        // http://bugzilla.xamarin.com/show_bug.cgi?id=2761
        rng.GetBytes(bytes);
        a = new BigInteger(bytes);
      }
      while(a < 2 || a >= source - 2);

      BigInteger x = BigInteger.ModPow(a, d, source);
      if(x == 1 || x == source - 1)
        continue;

      for(int r = 1; r < s; r++)
      {
        x = BigInteger.ModPow(x, 2, source);
        if(x == 1)
          return false;
        if(x == source - 1)
          break;
      }

      if(x != source - 1)
        return false;
    }

    return true;
  }
}
Wendywendye answered 19/6, 2014 at 0:19 Comment(12)
so you increment by 10 at a time, and only check 4 of the 10. But you can increment by 30, and only check 8 of the 30. Of course, 8/30 = 4/15 < 4/10. Then there's 48/210.Resolvable
I'm not sure what you mean, but the idea is to cover as many prime divisors as possible past a certain threshold. The more restrictive it becomes, the better. Are you trying to explain a method of making it more restrictive?Wendywendye
starting with 7, increment by 30. which numbers from 7 to 36 do you really need? such that aren't multiples of 2,3 or 5. There are only 8 of them.Resolvable
You would need 17, since its a prime.Wendywendye
You need to cover all primes between 7 and 36, so yes, 19 included. You need to cover the primes, 7, 11, 13, 17, 19, 23, 29, and 31 in that range.Wendywendye
Yeah, I kind of see what you mean, but how would you know which of that set of yours you would check? Like you said before, increment by 30 and check 8, but, firstly, I'm not sure that would always hold for different ranges. Secondly, I'm not sure how you'd know what values to check (what 8 values of the 30)...Wendywendye
you increment each of the eight numbers by 30, each time. see "Wheel factorization" (although WP article is badly written IMO). also: stackoverflow.com/a/21310956/849891 -- 2*3*5 = ....Resolvable
@WillNess Yes, you are right. I see what you mean. Heh, essentially what I did was implement a low-level wheel factorization algorithm. This is very interesting as a factoring method. You could extend what I've done above for more values. Do you know if there are limits to the value of n that you choose for the wheel factorization?Wendywendye
there is no limit but the returns are quickly diminishing for the rapidly growing investments: it's 1/2, 2/6, 8/30, 48/210, 480/2310, ... = 0.5, 0.3333, 0.2667, 0.2286, 0.2078, ... so the gains are 50%, 25%, 16.67%, 10%, ... for 2x, 4x, 6x, 10x, ... more numbers on the wheel to deal with. And if we do it with loop unrolling, it means 2x, ..., 10x, ... code blowup.Resolvable
@WillNess If you break factoring, you break the internet and most encryption standards. Is there no pattern to be discovered here? I wonder if you were to put this relationship into a mathematical algorithm as n approaches infinity, when the gains are at maximum, if there would be a relationship with the spokes of primes from the wheel, kind of like what I tried to do here: math.stackexchange.com/questions/840308/…. Also, "Windows Server 2012 Standard Edition supports up to 64 sockets and up to 640 logical processors."Wendywendye
... so "return on investment" is 25%, 6.25%, 2.8%, 1%, ... so it doesn't pay much to enlarge the wheel past 11. Each wheel of circumference PRODUCT(p_i){i=1..n} contains PRODUCT(p_i - 1){i=1..n} spikes but gets us without composites only up to (p_(n+1))^2. Rolling the 100-primes wheel we only get primes up to 547^2=299209, but there are 4181833108490708127856970969853073811885209475016770818056714802062057564305290‌348961566798327912719763961768373051814396765475489229643362657214962862299679072‌90044555142202583817713509990400000000000000000000000000000 spikes on that wheel.Resolvable
Coming to this late, you could re-implement github.com/kimwalisch/primesieve in C#... they use 3 methods to create a bitmask of primes. 1) a 210 (2x3x5x7) wheel. 2) a list of primes < block size that will need to be applied to every block. 3) lists to track primes that will only apply to one block. I would first check mod(n,210), then generate a list of primes up to sqrt(n), testing each against n.Pinochle
P
5

Here's a good example. I'm dropping the code in here just in case the site goes down one day.

using System;

class Program
{
    static void Main()
    {
    //
    // Write prime numbers between 0 and 100.
    //
    Console.WriteLine("--- Primes between 0 and 100 ---");
    for (int i = 0; i < 100; i++)
    {
        bool prime = PrimeTool.IsPrime(i);
        if (prime)
        {
        Console.Write("Prime: ");
        Console.WriteLine(i);
        }
    }
    //
    // Write prime numbers between 10000 and 10100
    //
    Console.WriteLine("--- Primes between 10000 and 10100 ---");
    for (int i = 10000; i < 10100; i++)
    {
        if (PrimeTool.IsPrime(i))
        {
        Console.Write("Prime: ");
        Console.WriteLine(i);
        }
    }
    }
}

Here is the class that contains the IsPrime method:

using System;

public static class PrimeTool
{
    public static bool IsPrime(int candidate)
    {
    // Test whether the parameter is a prime number.
    if ((candidate & 1) == 0)
    {
        if (candidate == 2)
        {
        return true;
        }
        else
        {
        return false;
        }
    }
    // Note:
    // ... This version was changed to test the square.
    // ... Original version tested against the square root.
    // ... Also we exclude 1 at the end.
    for (int i = 3; (i * i) <= candidate; i += 2)
    {
        if ((candidate % i) == 0)
        {
        return false;
        }
    }
    return candidate != 1;
    }
}
Palmore answered 1/4, 2013 at 12:9 Comment(2)
OP just wanted to check if a given number is prime or not, not calculate all primes between two numbers.Indicative
@ParasWadehra The IsPrime method does exactly what the OP wanted. The code that shows the numbers is just an example of how it can be used.Chuckwalla
G
3
/***
 * Check a number is prime or not
 * @param n the number
 * @return {@code true} if {@code n} is prime
 */
public static boolean isPrime(int n) {
    if (n == 2) {
        return true;
    }
    if (n < 2 || n % 2 == 0) {
        return false;
    }
    for (int i = 3; i <= Math.sqrt(n); i += 2) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}
Gerrilee answered 5/10, 2019 at 11:19 Comment(0)
L
2

This version calculates a list of primes square roots and only checks if the list of prime numbers below the square root, and uses a binarysearch in the list to find known primes. I looped through to check the first 1,000,000 primes, and it took about 7 seconds.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            //test();
            testMax();
            Console.ReadLine();
        }

        static void testMax()
        {
            List<int> CheckPrimes = Enumerable.Range(2, 1000000).ToList();
            PrimeChecker pc = new PrimeChecker(1000000);
            foreach (int i in CheckPrimes)
            {
                if (pc.isPrime(i))
                {
                    Console.WriteLine(i);
                }
            }
        }
    }

    public class PrimeChecker{
        public List<int> KnownRootPrimesList;
        public int HighestKnownPrime = 3;

        public PrimeChecker(int Max=1000000){
            KnownRootPrimesList = new List<int>();
            KnownRootPrimesList.Add(2);
            KnownRootPrimesList.Add(3);
            isPrime(Max);
        }

        public bool isPrime(int value)
        {
            int srt = Convert.ToInt32(Math.Ceiling(Math.Sqrt(Convert.ToDouble(value))));
            if(srt > HighestKnownPrime)
            {
                for(int i = HighestKnownPrime + 1; i <= srt; i++)
                {
                    if (i > HighestKnownPrime)
                    {
                        if(isPrimeCalculation(i))
                        {
                                KnownRootPrimesList.Add(i);
                                HighestKnownPrime = i;
                        }
                    }
                }
            }
            bool isValuePrime = isPrimeCalculation(value);
            return(isValuePrime);
        }

        private bool isPrimeCalculation(int value)
        {
            if (value < HighestKnownPrime)
            {
                if (KnownRootPrimesList.BinarySearch(value) > -1)
                {
                    return (true);
                }
                else
                {
                    return (false);
                }
            }
            int srt = Convert.ToInt32(Math.Ceiling(Math.Sqrt(Convert.ToDouble(value))));
            bool isPrime = true;
            List<int> CheckList = KnownRootPrimesList.ToList();
            if (HighestKnownPrime + 1 < srt)
            {
                CheckList.AddRange(Enumerable.Range(HighestKnownPrime + 1, srt));
            }
            foreach(int i in CheckList)
            {
                isPrime = ((value % i) != 0);
                if(!isPrime)
                {
                    break;
                }
            }
            return (isPrime);
        }

        public bool isPrimeStandard(int value)
        {
            int srt = Convert.ToInt32(Math.Ceiling(Math.Sqrt(Convert.ToDouble(value))));
            bool isPrime = true;
            List<int> CheckList = Enumerable.Range(2, srt).ToList();
            foreach (int i in CheckList)
            {
                isPrime = ((value % i) != 0);
                if (!isPrime)
                {
                    break;
                }
            }
            return (isPrime);
        }
    }
}
Lutes answered 29/1, 2016 at 22:16 Comment(0)
M
1

Based on @Micheal's answer, but checks for negative numbers and computes the square incrementally

    public static bool IsPrime( int candidate ) {
        if ( candidate % 2 <= 0 ) {
            return candidate == 2;
        }
        int power2 = 9;
        for ( int divisor = 3; power2 <= candidate; divisor += 2 ) {
            if ( candidate % divisor == 0 )
                return false;
            power2 += divisor * 4 + 4;
        }
        return true;
    }
Manchester answered 9/11, 2013 at 12:3 Comment(0)
A
1

Find this example in one book, and think it's quite elegant solution.

 static void Main(string[] args)
    {
        Console.Write("Enter a number: ");
        int theNum = int.Parse(Console.ReadLine());

        if (theNum < 3)  // special case check, less than 3
        {
            if (theNum == 2)
            {
                // The only positive number that is a prime
                Console.WriteLine("{0} is a prime!", theNum);
            }
            else
            {
                // All others, including 1 and all negative numbers, 
                // are not primes
                Console.WriteLine("{0} is not a prime", theNum);
            }
        }
        else
        {
            if (theNum % 2 == 0)
            {
                // Is the number even?  If yes it cannot be a prime
                Console.WriteLine("{0} is not a prime", theNum);
            }
            else
            {
                // If number is odd, it could be a prime
                int div;

                // This loop starts and 3 and does a modulo operation on all
                // numbers.  As soon as there is no remainder, the loop stops.
                // This can be true under only two circumstances:  The value of
                // div becomes equal to theNum, or theNum is divided evenly by 
                // another value.
                for (div = 3; theNum % div != 0; div += 2)
                    ;  // do nothing

                if (div == theNum)
                {
                    // if theNum and div are equal it must be a prime
                    Console.WriteLine("{0} is a prime!", theNum);
                }
                else
                {
                    // some other number divided evenly into theNum, and it is not
                    // itself, so it is not a prime
                    Console.WriteLine("{0} is not a prime", theNum);
                }
            }
        }

        Console.ReadLine();
    }
Ame answered 28/3, 2014 at 9:4 Comment(0)
C
1

You can also find range of prime numbers till the given number by user.

CODE:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Input a number to find Prime numbers\n");
            int inp = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("\n Prime Numbers are:\n------------------------------");
            int count = 0;

            for (int i = 1; i <= inp; i++)
            {
                for (int j = 2; j < i; j++) // j=2 because if we divide any number with 1 the remaider will always 0, so skip this step to minimize time duration.
                {
                    if (i % j != 0)
                    {
                        count += 1;
                    }
                }
                if (count == (i - 2))
                    {
                        Console.Write(i + "\t"); 
                    }

                count = 0;
            }

            Console.ReadKey();

        }
    }

Prime numbers

Casi answered 24/1, 2015 at 3:48 Comment(0)
M
1

I'm trying to get some efficiency out of early exit when using Any()...

    public static bool IsPrime(long n)
    {
        if (n == 1) return false;
        if (n == 3) return true;

        //Even numbers are not primes
        if (n % 2 == 0) return false;

        return !Enumerable.Range(2, Convert.ToInt32(Math.Ceiling(Math.Sqrt(n))))
            .Any(x => n % x == 0);
    }
Matchbook answered 21/3, 2018 at 11:6 Comment(1)
I like the solution, but it doesn't unclude 2 as a prime numberEvelynneven
I
1

Here is a version without the "clutter" of other answers and simply does the trick.

static void Main(string[] args)
{

    Console.WriteLine("Enter your number: ");
    int num = Convert.ToInt32(Console.ReadLine());
    bool isPrime = true;
    for (int i = 2; i < num/2; i++)
    {
        if (num % i == 0)
        {
            isPrime = false;
            break;
        }
    }
    if (isPrime)
        Console.WriteLine("It is Prime");
    else
        Console.WriteLine("It is not Prime");
    Console.ReadLine();
}
Ingoing answered 28/6, 2019 at 19:45 Comment(0)
N
1

Original Answer

  • A prime number is odd except 2
  • A prime number is not negative
  • 1 or 0 is neither prime nor composite

Approach

  1. Add a counter to check how many times the input number is divisible by i (and has 0 (zero) remainder)
  2. If counter is = 2, then input is prime, else not prime
  3. If counter is > 2 "break" to avoid unnecessary processes (if you want to count the factors of your input number remove " || counter > 2 " on the first if statement)
  4. Add this line of code at the 2nd if statement inside the for loop if you want to see how many numbers with remainder 0 (or factors are present) :
Console.WriteLine( $" {inputNumber} / {i} = { inputNumber / i} (remainder: {inputNumber % i})" ); 
  1. Add the line of code in number 4 (at the end of the for loop) to see all the all the numbers divided by your input number (in case you want to see the remainder output and the quotient)
Console.Write( "Enter a Positive Number: " );
int inputNumber = Convert.ToInt32( Console.ReadLine() );
int counter = 0;

    for ( int i = 1; i <= inputNumber; i++ ) {
        if ( inputNumber == 0 || inputNumber == 1 || counter > 2 ) { break; }
        if ( inputNumber % i == 0 ) { counter++; }
    }

    if ( counter == 2 ) {
        Console.WriteLine( $"{inputNumber} is a prime number." );
    } else if ( inputNumber == 1 || inputNumber == 0 ) {
        Console.WriteLine( $"{inputNumber} is neither prime nor composite." );
    } else {
        Console.WriteLine( $"{inputNumber} is not a prime number. (It is a composite number)" );
    }

My reference: https://www.tutorialspoint.com/Chash-Program-to-check-if-a-number-is-prime-or-not



Simplified Version:

I used uint here instead of int to avoid negative inputs.

public bool IsPrime(uint number)
{
    if (number <= 1) { return false; }

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

    return true;
}
Nepean answered 26/1, 2021 at 10:0 Comment(1)
I like your simplified version, it's a good naïve implementation albeit it wouldn't scale well with higher numbers. A (very, very small) optimisation is to return true for 2 & start the counter at 2 since we know that all numbers will be divisible by 1 so there's no point testing it. Therefore instead of having a counter you can simply return false as soon as number % i == 0. But it really is a super small optimisation: on my PC using LINQPad and Benchmark.Net it saved 0.222 seconds (less than 10% of total) when the input was 479001599 - the 9th factorial prime! I was just curious :)Emmetropia
P
1

Update

Added else if (value % 2 == 0) to eliminate even numbers. thanks to avl_sweden

Method

Extension version:

public static bool IsPrime(this int value)
{
    if (value < 2)
        return false;
    else if (value == 2)
        return true;
    else if (value % 2 == 0) /*updated*/
        return false;

    var root = Math.Sqrt(value);

    for (int i = 3; i <= root; i += 2)
    {
        if (value % i == 0)
            return false;
    }
    return true;
}

Check

var primes = Enumerable.Range(1, 100).Where(x => x.IsPrime());
Console.WriteLine(string.Join(", ", primes));
/* Output
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
*/

Usage

12.IsPrime()    //false
13.IsPrime()    //true
151.IsPrime()   //true
2.IsPrime()     //true
Psychoneurosis answered 30/10, 2021 at 19:18 Comment(2)
This algorithm considers 4 to be prime, which is wrong.Fescennine
You are absolutely right, I fixed it. thank you @FescenninePsychoneurosis
E
1

Here's one with an explenation:

// Checks whether the provided number is a prime number.
  public static bool IsPrime(int num) {
    if (num <= 1)
      return false; // 1 or less is never prime.
    if (num==2)
      return true; // 2 is always a prime number.

    // Trial Division: Tries to divide number with all of the numbers in range 1-to-square-root(number).
    // If the number did not divide with the numbers in this range it will not divide with any other number therefore it's prime.
    int bound = (int)Math.Floor(Math.Sqrt(num));

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

    return true;
  }
Erective answered 10/2, 2022 at 19:2 Comment(0)
B
0

The algorithm in the function consists of testing whether n is a multiple of any integer between 2 and sqrt (n). If it's not, then True is returned which means the number (n) is a prime number, otherwise False is returned which means n divides a number that is between 2 and the floor integer part of sqrt(n).

private static bool isPrime(int n)
        {
            int k = 2;
            while (k * k <= n)
            {
                if ((n % k) == 0)
                    return false;
                else k++;
            }
            return true;
        }
Baynebridge answered 24/5, 2017 at 16:27 Comment(1)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!Barouche
B
0

The algorithm in the function consists of testing whether n is a multiple of any integer between 2 and sqrt (n). If it's not, then True is returned which means the number (n) is a prime number, otherwise False is returned which means n divides a number that is between 2 and the floor integer part of sqrt(n).

Recursive version

        // Always call it as isPrime(n,2)
        private static bool isPrime(int n, int k)
        {
            if (k * k <= n)
            {
                if ((n % k) == 0)
                    return false;
                else return isPrime(n, k + 1);
            }
            else
                return true;
        }
Baynebridge answered 30/5, 2017 at 11:50 Comment(2)
Any large number is going to cause a StackOverflowExcpetion.Reisman
Correct. Because of the recursion deep level. That's way I first posted the iterative approach. Recursion is elegance ;)Baynebridge
G
0

Prime numbers are numbers that are bigger than one and cannot be divided evenly by any other number except 1 and itself.

@This program will show you the given number is prime or not, and will show you for non prime number that it's divisible by (a number) which is rather than 1 or itself?@

        Console.Write("Please Enter a number: ");
        int number = int.Parse(Console.ReadLine());
        int count = 2; 
        // this is initial count number which is greater than 1

        bool prime = true;
        // used Boolean value to apply condition correctly

        int sqrtOfNumber = (int)Math.Sqrt(number); 
        // square root of input number this would help to simplify the looping.  

        while (prime && count <= sqrtOfNumber)
        {
            if ( number % count == 0)
            {
            Console.WriteLine($"{number} isn't prime and it divisible by 
                                      number {count}");  // this will generate a number isn't prime and it is divisible by a number which is rather than 1 or itself and this line will proves why it's not a prime number.
                prime = false;
            }
            
            count++;
            
        }
        if (prime && number > 1)
        
        {
            Console.WriteLine($"{number} is a prime number");
        }
        else if (prime == true)
        // if input is 1 or less than 1 then this code will generate
        {
            Console.WriteLine($"{number} isn't a prime");
        }
        
Gilbart answered 2/12, 2017 at 13:27 Comment(2)
This is exactly the same principal solution as the most upvoted answer, except that it also checks all even numbers which is unnecessary. Not only was it not necessary to post yet another version of the most upvoted answer, posting a bad implementation of it is definitely not needed.Warton
nope it's most simplify answer that anyone could understand as beginner,, i used here several number's to check because i want to find why the number isn't prime and which is the divisible number of it. i think you got my point of viewGilbart
T
0
function isPrime(n) {

    //the most speedly function

    var res = '';
    var is_composite = false;
    var err = false;
    var sqrt = Math.sqrt(n);

    if (n <= 1){
        err = true;
    }

    if (n == 2 || n == 3){

        res = true; //"Prime"

    } else if(n % 2 == 0 || n % 3 == 0) {

        res = false; //'Composite'

    } else{

        /*here you just neet to check dividers like (6k+1) or (6k-1)
          other dividers we exclude in if(n % 2 == 0 || n % 3 == 0)*/

        for(let i = 5; i <= sqrt; i += 6){
            if (n % i == 0){
                is_composite = true;
                break;
            }
        }

        if (!is_composite){
            for(let i=7; i <= sqrt; i += 6){
                if (n % i == 0){
                    is_composite = true;
                    break;
                }
            }
        }

        if (is_composite){
            res = false; //'Composite'
        } else {
            res = true; //'Prime'
        }
    }

    if (err) {
        res = 'error';
    }

    return res;
}
Tinct answered 4/3, 2021 at 22:0 Comment(0)
H
0

HackerRank Challenge (Running Time and Complexity): for multiple testcase, Prime Number.

Input Format: The first line contains an integer,T , the number of test cases. Each of the T subsequent lines contains an integer, n, to be tested for primality.

 int T = Convert.ToInt32(Console.ReadLine());
        int[] ar = new int[T];   

        for (int i = 0; i < ar.Length; ++i)
        {
            ar[i] = Convert.ToInt32(Console.ReadLine());
        }

        List<string> result = new List<string>();
        bool flag = true;
        for (int r = 0; r < ar.Length; ++r)
        {
            for (int i =2; i < (ar[r]>1000? ar[r]/4:ar[r]); ++i)
            {
                if (i != 1 && i != ar[r])
                {
                    if (ar[r] % i == 0)
                    {
                        flag = false;
                        break;
                    }
                }
            }

            if (flag && ar[r]!=1)
                result.Add("Prime");
            else
            {
                result.Add("Not prime");
                flag = true;
            }
              

        }

        foreach (var a in result)
        {
            Console.WriteLine(a);
        }
Hord answered 11/12, 2021 at 6:47 Comment(0)
G
0

It might helpful.

boolean isPrime(int n)
{
 if(n==2) return true;
 if(n==1 || n%2==0) return false;

 int d,root;

 for(d=3,root=(int)Math.sqrt(n);d<=root && n%d!=0;d+=2);
 
 if(d>root) return true;
 return false;
}
Gunilla answered 16/1, 2022 at 15:58 Comment(0)
I
0
public bool IsPrime(int num1)
  {
    if (n<2)
      return false;
    for (int a = 2; a <= Math.Sqrt(num1); a++)
    {
        if (num1 % a == 0)
        {
            Console.WriteLine(num1 + " is not prime number");
            return false;
        }

    }
    return true;
  }
Impious answered 9/1, 2023 at 18:15 Comment(0)
C
0

This is a basic implementation without ERROR checking (of course, there is always a way to improve. This is a sample implementation that I was trying to show to my son (3rd grade) written in 5 minutes. (Sorry, it's in Java and pretty sure you can convert into C#)

import java.util.ArrayList;
import java.util.List;

public class PrimeNumber {
  
  public boolean isPrime(int input) {
    for (int i = 2; i <= input; i++) {
      if (input == i) continue;
      else {
        if (input % i == 0) {
          System.out.println("Oooo Oh. Looks like the first number that the input number can be divided by is %s".formatted(i));
          return false;
        }
      }
    }
    
    return true;
  }
  
  public boolean isPrimeWithResult(int input) {
    List<Integer> listOfDividers = new ArrayList<>();
    
    for (int i = 2; i <= input; i++) {
      if (input == i) continue;
      else {
        if (input % i == 0) {
          listOfDividers.add(i);
        }
      }
    }
    
    if (listOfDividers.isEmpty()) return true;
    else {
      System.out.print("Looks like there is a list of Dividers for this number (%s): ".formatted(input));
      System.out.println(listOfDividers);
      return false;
    }
  }
  
  public static void main(String[] args) {
    PrimeNumber pn = new PrimeNumber();
    
    int input = Integer.parseInt(args[0]);
    
    System.out.println("Is the input (%s) number a prime? %s".formatted(input, pn.isPrimeWithResult(input)));
  }
}
Chlamys answered 5/6 at 0:20 Comment(0)
A
-1
   bool flag = false;


            for (int n = 1;n < 101;n++)
            {
                if (n == 1 || n == 2)
                {
                    Console.WriteLine("prime");
                }

                else
                {
                    for (int i = 2; i < n; i++)
                    {
                        if (n % i == 0)
                        {
                            flag = true;
                            break;
                        }
                    }
                }

                if (flag)
                {
                    Console.WriteLine(n+" not prime");
                }
                else
                {
                    Console.WriteLine(n + " prime");
                }
                 flag = false;
            }

            Console.ReadLine();
Amaras answered 24/4, 2014 at 7:57 Comment(1)
This code runs and finds whether each number up to 100 is prime or not. That is not the objective of this question.Indicative
J
-1

Only one row code:

    private static bool primeNumberTest(int i)
    {
        return i > 3 ? ( (Enumerable.Range(2, (i / 2) + 1).Where(x => (i % x == 0))).Count() > 0 ? false : true ) : i == 2 || i == 3 ? true : false;
    }
Jacquelinjacqueline answered 11/5, 2014 at 7:43 Comment(1)
.Where(x => (i % x == 0))).Count() > 0 ? false : true is more concisely (and efficiently) expressed as .All(x => i%x != 0). Also, ? true : false is unnecessary. Finally, this isn't code golf. What's the advantage of packing all that logic into one line?Stockroom
A
-1

Try this code.

bool isPrimeNubmer(int n)
{
    if (n == 2 || n == 3) //2, 3 are prime numbers
        return true;
    else if (n % 2 == 0) //even numbers are not prime numbers
        return false;
    else
    {
        int j = 3;
        int k = (n + 1) / 2 ;

        while (j <= k)
        {
            if (n % j == 0)
                return false;
            j = j + 2;
        }
        return true;
    }
}
Aphasia answered 26/5, 2015 at 16:24 Comment(1)
1 is not a prime numberSuboxide
D
-1

I think this is a simple way for beginners:

using System;
using System.Numerics;
public class PrimeChecker
{
    public static void Main()
    {
    // Input
        Console.WriteLine("Enter number to check is it prime: ");
        BigInteger n = BigInteger.Parse(Console.ReadLine());
        bool prime = false;

    // Logic
        if ( n==0 || n==1)
        {
            Console.WriteLine(prime);
        }
        else if ( n==2 )
        {
            prime = true;
            Console.WriteLine(prime);
        }
        else if (n>2)
        {
            IsPrime(n, prime);
        }
    }

    // Method
    public static void IsPrime(BigInteger n, bool prime)
    {
        bool local = false;
        for (int i=2; i<=(BigInteger)Math.Sqrt((double)n); i++)
        {
            if (n % i == 0)
            {
                local = true;
                break;
            }
        }
        if (local)
            {
                Console.WriteLine(prime);
            }
        else
        {
            prime = true;
            Console.WriteLine(prime);
        }
    }
}
Disentomb answered 9/12, 2015 at 18:34 Comment(1)
It would be nice to also add a brief explanation of what the code does and what is the core idea behind it - that would make the answer more useful end easy to read for beginners. And welcome to StackOverflow!Transience
D
-1

This is the simplest way to find prime number is

for(i=2; i<num; i++)
        {
            if(num%i == 0)
            {
                count++;
                break;
            }
        }
        if(count == 0)
        {
            Console.WriteLine("This is a Prime Number");
        }
        else
        {
            Console.WriteLine("This is not a Prime Number");
        }

Helpful Link: https://codescracker.com/java/program/java-program-check-prime.htm

Dawes answered 7/4, 2019 at 12:1 Comment(1)
Doesn't check negative, and because you are not taking sqrt of the number and iterating you end up doing way more loops than necessary. tested with 300003 as the number and it looked 79 times. With sqrt first looks only 2-3 times. and fails on a list of primes from 2 to 100.Henrietta
V
-1

I think this is the easiest way to do it.

static bool IsPrime(int number)
{
   if (number <= 0) return false;
   for (int i = 2; i <= number/2; i++)
       if (number % i == 0)
           return false;
    return true;
}
Vaporous answered 24/11, 2019 at 13:53 Comment(1)
Edited, only add a negative number check.Matrilineal
O
-1

Shortest & fastest way to find the Prime Number using conventional technique.

public bool IsPrimeNumber(int Number)
{
    if (Number <= 1) 
        return false;

    if (Number == 2) 
        return true;

    if (Number % 2 == 0) 
        return false;

    int i = 2, j = Number / 2;

    for (; i <= j && Number % 2 != 0; i++);

    return (i - 1) == j;
}
Obstruction answered 15/6, 2022 at 15:23 Comment(1)
This answer returns true for a Number of 9 (9 is not prime).Infinite
D
-2

You can also try this:

bool isPrime(int number)
    {
        return (Enumerable.Range(1, number).Count(x => number % x == 0) == 2);
    }
Dodie answered 5/9, 2017 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.