none
It works but sometimes it runs and sometimes it doesn't RRS feed

  • Question

  • So I just started learning c# but it wasn't that hard because i already had my basics in C (arduino). I wanted to learn game design but i needed to try learning c# first. I made my second project a Prime Number calculator where there are two main modes. The first mode checks if your input number is prime or not, and the second makes list primes in between your input starting value and ending value. The problem is that sometimes when I input my value and press enter, nothing shows up. I'm not really sure why but I think it might be because I set the bar kind of high with unsigned long for every input. Please take this code and if it works, keep playing with it. It doesn't take long for the bug to show up, for me atleast.

    But anyways here's my code:

    using System;

    namespace Prime_Numbers_calculator
    {
        class Program
        {
            public static decimal x;
            public static ulong pd;
            public static int mc;
            public static bool gtfo;
            static void Main(string[] args)
            {
                for (int y = 0; y < 1; y++)
                {
                    Console.WriteLine("Welcome to prime number calculator, please press any key to proceed.");
                    Console.ReadKey();
                }
                Console.Clear();
                while (true)
                {
                    MM();
                    if (mc == 0)
                    {
                        Console.Clear();
                        PC();
                        Console.WriteLine("Press any key to proceed.");
                        Console.ReadKey();
                    }
                    else if (mc == 1)
                    {
                        Console.Clear();
                        PVINP();
                        Console.WriteLine("Press any key to proceed.");
                        Console.ReadKey();
                    }
                    EM();
                    Console.Clear();
                    if (gtfo == true)
                    {
                        Console.WriteLine("Thank you for using Prime Number Calculator");
                        break;
                    }
                }
            }
            static void PC()//Program that checks if num(input) = prime
            {
                ulong num;
                Console.Write("Please enter a number");
                Console.WriteLine(", The limit is about 18.4 quintrillion");
                num = Convert.ToUInt64(Console.ReadLine());
                Console.WriteLine("Your answer is:");
                x = num;
                pd = 2;
                while (true)
                {
                    if (num == 2)
                    {
                        Console.WriteLine("{0} is a prime number because it can't be divided by anything under half of {1}({2})", num, num, x / 2);
                        Console.WriteLine("to get a result of a whole number meaning that it only has 2 factors which is 1 and {0}.", num);
                        break;
                    }
                    else if (num / 2 == x / 2)//check if num = even
                    {
                        Console.WriteLine("{0} isn't a prime number because it can be divided by 2", num);
                        break;
                    }
                    else if (num / 5 == x / 5)//check if num = even
                    {
                        Console.WriteLine("{0} isn't a prime number because it can be divided by 5", num);
                        break;
                    }
                    else if (num / pd == x / pd)//checks if num can be divided by other primes
                    {
                        Console.WriteLine("{0} isn't a prime number because it can be divided by {1}", num, pd);
                        break;
                    }
                    else if (num / pd != x / pd && pd < x / 2)//if can't be divided, prime divider +2
                    {
                        pd = pd + 2;
                    }
                    else if (pd > num / 2)//The program comes to conclusion that num = prime
                    {
                        Console.WriteLine("{0} is a prime number because it can't be divided by anything under half of {1}({2})", num, num, x/2);
                        Console.WriteLine("to get a result of a whole number meaning that it only has 2 factors which is 1 and {0}.", num);
                        break; 
                    }
                }

            }    
            static void PVINP()//Program that makes a list of primes from your starting-ending value input
            {
                ulong cc;
                Console.WriteLine("Please enter your starting value, The limit is about 18.4 quintrillion");
                ulong min = Convert.ToUInt64(Console.ReadLine());
                Console.WriteLine("Please enter your ending value, The limit is about 18.4 quintrillion");
                ulong max = Convert.ToUInt64(Console.ReadLine());
                Console.WriteLine("Here are the prime values between {0} and {1}", min, max);
                pd = 2;
                cc = min;
                while(cc < max+1)//repeated until counting value > max value
                {
                    x = cc;
                    if (cc == 2)
                    {
                        Console.WriteLine(cc);
                        cc++;
                    }
                    else if (cc / 2 == x / 2)//checks if num = even
                    {
                        cc++;
                    }
                    else if (cc / 5 == x / 5)//check if num can be divided by 5
                    {
                        cc = cc + 2;
                        break;
                    }
                    else if (cc / pd == x / pd)//checks if num can be divided by other primes
                    {
                        cc = cc + 2;
                    }
                    else if (cc / pd != x / pd && pd < x / 2)//if can't be divided, prime divider +2
                    {
                        pd = pd + 2;
                    }
                    else if (pd > x / 2)//The program comes to conclusion that num = prime
                    {
                        Console.WriteLine(cc);
                        cc = cc + 2;
                        pd = 3;
                    }
                }
            }
            static void MM()//Main menu
            {
                mc = 2;
                Console.WriteLine("Please select a mode");
                Console.WriteLine("Press A to Check if the number is prime or not");
                Console.WriteLine("Press S to Show all prime values in a period of numbers");
                for (int i = 0; i < 1;)
                {
                    var ki = Console.ReadKey();
                    switch (ki.Key)
                    {
                        case ConsoleKey.A:
                            Console.WriteLine("\nYou chose the first option");
                            i++;
                            mc = 0;
                            break;
                        case ConsoleKey.S:
                            i++;
                            mc = 1;
                            Console.WriteLine("\nYou chose the second option");
                            break;
                        default:
                            break;
                    }
                }
            }
            static void EM()//Ending menu
            {
                gtfo = false;
                Console.Clear();
                Console.WriteLine("Use Prime Number Calculator again?");
                Console.WriteLine("Press SPACEBAR to reuse.");
                Console.WriteLine("Press ENTER to leave");
                for (int i = 0; i < 1;)
                {
                    var ki = Console.ReadKey();
                    switch (ki.Key)
                    {
                        case ConsoleKey.Spacebar:
                            Console.WriteLine("\nYou chose to reuse the calculator");
                            i++;
                            break;
                        case ConsoleKey.Enter:
                            i++;
                            gtfo = true;
                            Console.WriteLine("\nYou chose to leave");
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }   

    Monday, March 9, 2020 5:42 PM

All replies

  •  The problem is that sometimes when I input my value and press enter, nothing shows up. I'm not really sure why but I think it might be because I set the bar kind of high with unsigned long for every input. Please take this code and if it works, keep playing with it. It doesn't take long for the bug to show up, for me atleast.


    When you say "nothing shows up" I assume you mean the result doesn't appear.
    If so, how long did you wait? It may be that the calculations are taking so 
    long that it will be *many* minutes before they are completed. For example,
    if you choose option A and enter 4123456789 it will take a very long time 
    before all calculations are completed.

    You can get a sense of its progress if you insert a periodic display such as
    checking when the variable pd reaches certain milestones. e.g. -

    pd = 2;
    while (true)
    {
        //if((pd % 1000000000) == 0)
        if((pd % 100000000) == 0)
        {
            Console.WriteLine("pd = {0}", pd);
        }
        
    

    When testing with such lengthy calculations, a Release Build will often execute    
    faster than a Debug Build. However, it will still take considerable time to do
    billions of calculations.

    - Wayne


    Monday, March 9, 2020 7:52 PM
  • An example Release build run with the display added that I suggested:

    Please enter a number, The limit is about 18.4 quintrillion
    4123456789
    Your answer is:
    pd = 1000000000
    pd = 2000000000
    4123456789 is a prime number because it can't be divided by anything under half
    of 4123456789(2061728394.5)
    to get a result of a whole number meaning that it only has 2 factors which is 1
    and 4123456789.
    Press any key to proceed.

    - Wayne

    Monday, March 9, 2020 8:03 PM
  • I think some of your problem is that you don't know how to program and are adding things that do nothing (aka your for loops) and using meaningless names (e.g. MM, EM). This is making your code almost impossible to understand. I strongly recommend that you either get a getting started book on C# or take some online tutorials before you get too much further and learn bad habits that will hurt you later. Let's start with some general guidelines.

    1) If you don't need to do something more than once then you don't need a looping constructor (while, for, do).

    2) Identifier names have no impact on the speed or size of compilation or runtime and therefore you always use descriptive names. `MM` is meaningless and only hurts the reader of the code. `DisplayMainMenu` is descriptive, has zero impact on performance and is easier to understand. Functions/methods are always actions and therefore are named using verbs.

    3) In C# at least using a `for` loop is rare. If you need to loop until some arbitrary condition occurs then use a `do-while` or `while`. If you need to enumerate sets of items (the common use case for a `for` loop) then use `foreach` instead. The only time you should need a `for` loop is if you need a fixed iteration (> 1) or the index is important (rare outside arrays).

    4) Unless working inside a class use parameters to pass data to functions and return types to return data from functions.

    5) Prefer `switch` statements over `if-else` when doing equality checking.

    Let's clean up your code and see if we can narrow down the problem.

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Welcome to prime number calculator, please press any key to proceed.");
            Console.ReadKey();
                
            Console.Clear();
    
            while (true)
            {
                //Could use an enum here to make it more readable
                switch (MainMenu())
                {
                    case 0: GetPrime(); break;
                    case 1: GetPrimes(); break;                        
                };
    
                //Probably could add this to the ShouldContinue method??
                Console.WriteLine("Press any key to proceed.");
                Console.ReadKey();
    
                if (!ShouldContinue())
                {
                    Console.WriteLine("Thank you for using Prime Number Calculator");
                    return;
                };
            }
        }
    
        static ulong ReadUInt64 ()
        {
            do
            {
                var input = Console.ReadLine();
    
                if (UInt64.TryParse(input, out var result))
                    return result;
    
                Console.WriteLine("Not a valid number");
            } while (true);
        }
    
        //Program that checks if num(input) = prime
        static void GetPrime()
        {            
            Console.Write("Please enter a number");
            Console.WriteLine(", The limit is about 18.4 quintrillion");
    
            //Let's make this safe
            var num = ReadUInt64();
                
            Console.WriteLine("Your answer is:");
    
            if (IsPrime(num, out var divider))
            {
                //Trying to emulate your UI logic in this function so IsPrime just does the work...
                if (num == 2)
                {
                    Console.WriteLine("{0} is a prime number because it can't be divided by anything under half of {1}({2})", num, num, num / 2);
                    Console.WriteLine("to get a result of a whole number meaning that it only has 2 factors which is 1 and {0}.", num);
                }
                else if (divider == 2)
                    Console.WriteLine("{0} isn't a prime number because it can be divided by 2", num);
                else if (divider == 5)
                    Console.WriteLine("{0} isn't a prime number because it can be divided by 5", num);
                else
                {
                    Console.WriteLine("{0} is a prime number because it can't be divided by anything under half of {1}({2})", num, num, num / 2);
                    Console.WriteLine("to get a result of a whole number meaning that it only has 2 factors which is 1 and {0}.", num);
                };
            } else
            {
                Console.WriteLine("{0} isn't a prime number because it can be divided by {1}", num, divider);                
            };
        }
    
        static bool IsPrime ( ulong value, out ulong divider )
        {
    
            //This really doesn't seem to do anything, since x is never changing nor is num then both x and num 
            //will always have the same value...
            var x = value;
    
            var primeDivider = 2UL;
            while (true)
            {
                if (value < 2)
                {
                    divider = value;
                    return true;
                }
                else if (value % 2 == 0)//check if num = even
                {
                    divider = 2;
                    return false;
                }
                else if (value % 5 == 0)//check if num = even
                {
                    divider = 5;
                    return false;
                }  //This line should always be true if num and x are always the same
                else if (value / primeDivider == x / primeDivider)//checks if num can be divided by other primes
                {
                    divider = primeDivider;
                    return false;                    
                }  //This line should always be false if num and x are always the same
                else if (value / primeDivider != x / primeDivider && primeDivider < x / 2)//if can't be divided, prime divider +2
                {
                    primeDivider += 2;
                }
                else if (primeDivider > value / 2)//The program comes to conclusion that num = prime
                {
                    divider = 0;
                    return true;                    
                }
            }
        }
    
        static void GetPrimes()//Program that makes a list of primes from your starting-ending value input
        {            
            Console.WriteLine("Please enter your starting value, The limit is about 18.4 quintrillion");
            ulong min = ReadUInt64();
                
            Console.WriteLine("Please enter your ending value, The limit is about 18.4 quintrillion");
            ulong max = ReadUInt64();
    
            Console.WriteLine("Here are the prime values between {0} and {1}", min, max);
    
            //This seems to calculate prime all over again but you shouldn't need to do that
            for (var value = min; value <= max; ++value)
            {
                if (IsPrime(value, out var divider))
                    Console.WriteLine(value);
            };
        }
            
        static int MainMenu()
        {            
            Console.WriteLine("Please select a mode");
            Console.WriteLine("Press A to Check if the number is prime or not");
            Console.WriteLine("Press S to Show all prime values in a period of numbers");
    
            do
            {
                var ki = Console.ReadKey();
                switch (ki.Key)
                {
                    case ConsoleKey.A:
                        Console.WriteLine("\nYou chose the first option");
                        return 0;
                    case ConsoleKey.S:
                        Console.WriteLine("\nYou chose the second option");
                        return 1;                    
                };
            } while (true);
        }
    
        static bool ShouldContinue()
        {
            Console.Clear();
            Console.WriteLine("Use Prime Number Calculator again?");
            Console.WriteLine("Press SPACEBAR to reuse.");
            Console.WriteLine("Press ENTER to leave");
    
            do
            {
                var ki = Console.ReadKey();
                switch (ki.Key)
                {
                    case ConsoleKey.Spacebar:
                        Console.WriteLine("\nYou chose to reuse the calculator");
                        return true;
                    case ConsoleKey.Enter:
                        Console.WriteLine("\nYou chose to leave");
                        return false;                    
                };
            } while (true);
        }
    }

    Now that the code is cleaned up it should be easier to debug this. Set a breakpoint on the IsPrime method and step through the code for whatever value you're testing. If, for example you're testing 3, then you can see where the logic should be going as you step through your algorithm. If it doesn't do what you expect then the problem is likely at that point. Additionally, by cleaning up the code, we've eliminated the dependency on global variables which means running the code multiple times (during the same run) shouldn't cause old values to be used which is often the problem when you see behavior change across runs of the same code.

    Your prime calculation function doesn't seem correct to me. Can you identify the source algorithm for this code? As an example powers of 3 are primes as well but your code is just checking 2 and 5. There are a lot more primes as well (powers of 7, 11, etc). The easiest algorithm is to eliminate the easy cases like 2, 3, 5 using modulo and then enumerate remaining values until you find division. For C# here's an impl (https://stackoverflow.com/questions/1510124/program-to-find-prime-numbers/1510199). Of course it won't perform well with large numbers. That is where I've seen prime tables used instead. The larger the prime table the faster the calculation at the cost of memory.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, March 9, 2020 8:05 PM
    Moderator
  • An example Release build run with the display added that I suggested:

    Please enter a number, The limit is about 18.4 quintrillion
    4123456789
    Your answer is:
    pd = 1000000000
    pd = 2000000000
    4123456789 is a prime number because it can't be divided by anything under half
    of 4123456789(2061728394.5)
    to get a result of a whole number meaning that it only has 2 factors which is 1
    and 4123456789.

    Incidentally, I'm not sure the result shown from your program for 4123456789
    is correct. I believe 4123456789 can be evenly divided by 191.

    - Wayne

    Monday, March 9, 2020 8:14 PM
  • Hi Luka,

    Thank you for posting here.

    Other people have put forward a lot of good suggestions, now let me talk about the problem I see.

    When I ran your code, I noticed that you have a method to get all prime numbers in a certain range.

    However, when I tried this function, I got the wrong answer. Michael Taylor also mentioned that this algorithm is not rigorous.

    Try this method to get the correct result.

       static void GetAllPrimeInRange()//Program that makes a list of primes from your starting-ending value input
            {
                ulong cc;
                Console.WriteLine("Please enter your starting value, The limit is about 18.4 quintrillion");
                ulong min = Convert.ToUInt64(Console.ReadLine());
                Console.WriteLine("Please enter your ending value, The limit is about 18.4 quintrillion");
                ulong max = Convert.ToUInt64(Console.ReadLine());
                Console.WriteLine("Here are the prime values between {0} and {1}", min, max);
                pd = 2;
                cc = min;
                for (ulong i = cc; i <= max; i++)
                {
                    for (ulong k = 2; k <= i; k++)
                    {
                        if (i % k == 0 && i != k)
                        {
                            break;
                        }
                        if (i % k == 0 && i == k)
                        {
                            Console.WriteLine(i);
                        }
                    }
                }
            }

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, March 10, 2020 2:13 AM
  • Thanks for suggesting my bad habits, I'll take that into consideration next time I make another code.

    Also this is how my prime algorithm for the first mode works just so you understand correctly:

    Prime numbers are all odds except for the number two, so We first divided our input by 2 to check if our input is even.

    If the results suggests that it isn't a even value, then we start divided our input with odd numbers because it would make me go through more trouble to use only primes to divided it so making it odd by starting with 3 and adding 2 each time will make it convenient.

    Here we will compare two varibles which is our ulong input (Whole number) and float x(Decimal). If we divided both  of them with of prime divider(pd), it should indicate if the number is prime or not.

    Here's an example:

    Input - 11

    float x = 11 also

    5(Input(11/2)) = 5.5(x(11/2)), so the input is not an even number

    3(Input(11/3)) = 3.6666...(x(11/3)), so the input cannot be divided by 3

    then the program keeps repeat this process and when each process ends, The program will make our prime divider value be added by two so it can never be even. ex: 3 - 5 -7 -9

    So every time it adds, the input will be divided by a new odd value even if that odd value isn't a prime. The process will keep happening until our prime divider surpasses The value of of our input/our old PD value before our current one. ex: current PD = 5 then checks if PD > Input/3. I might have not included this in my last code bacuse in the code I posted, I used 2.

    Another example for if our input isn't prime

    Input = 15

    x = 15

    7(Input(15/2)) = 7.5(x(15/2)), so the input is not an even number

    5(Input(15/3)) = 5(x(15/3)), so the input can be divided by 3 because there are no decimals. X and input has the same exact value. Therefore 15 is not a prime number.

    I just wanted to point out my algorithm for my prime checking function, although I still have no clear algorithm for my other function which is primes in a certain period. It is supposed to repeat my prime checking function from Input(min)-Input(Max).

    Anyways, thanks for suggesting possible corrections for my codes, and for looking out mistakes are often made. Have a good day :)

    Thursday, March 12, 2020 8:00 AM
  • static void prime()
    {
    Console.WriteLine("Please select a mode 1 for single and 2 for range of prime check");
    var Choice = Console.ReadLine();
    Console.WriteLine("Please select a number/numbers by , separators");
    
    var input = Console.ReadLine();
    if(Choice == "1")
    {
      if (UInt64.TryParse(input, out var result))
      {
      	if(checkprime(result)
    	 Console.WriteLine("A valid prime number");
    	 else
    	 Console.WriteLine("Not a valid number");
      }
    
    }
    else if(Choice == "2")
    {
    var inputs = input.split(",");
    for(int i =0;i<inputs.length;i++)
    {
    if (UInt64.TryParse(inputs[i], out var result))
      {
      	if(checkprime(result)
    	 Console.WriteLine(relust + ",");
    	  }
    
    
    }
    }
    
    }
    
    public static bool checkprime(int n)
    {
    var count = 0;
    if (n == 2 || n==1)
    return true;
    else
    {
    for(int i=1;i<=n;i++)
    {
    if(n%1==0) count++;
    }
    if(count <= 2)
    return true;
    }
    return false
    
    }

    Thursday, March 12, 2020 10:14 AM
  • OK so your prime algorithm isn't correct then. Use this adjusted algorithm in the code I posted and it should work for both scenarios you identified.

    static bool IsPrime(ulong value, out ulong divider)
    {
        //Easy cases
        if (value <= 2 || value == 3 || value == 5 || value == 7)
        {
            divider = 0;
            return true;
        } else if (value % 2 == 0)
        {
            divider = 2;
            return false;
        } else if (value % 3 == 0)
        {
            divider = 3;
            return false;
        } else if (value % 5 == 0)
        {
            divider = 5;
            return false;
        };            
    
        //Enumerate remaining values
        for (ulong prime = 7; prime < value; prime += 2)
        {
            if (value % prime == 0)
            {
                divider = prime;
                return false;
            };
        };
    
        divider = 0;
        return true;
    }
    The function starts by eliminating the most common primes such as really small numbers, evens, and powers of 3 and 5. Then it starts with 7 (the first possible value) and divides the rest. I verified the algorithm works against the first 100 numbers. So using this method both your "is a prime" functionality and "all primes in range" work correctly.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, March 12, 2020 2:05 PM
    Moderator