- Joined
- Jun 28, 2007
- Messages
- 2,983
- Reaction score
- 3
Hi,
Inspired by Kyle Enos's great 2 tutorial threads, I thought about making a tutorial too
. About calculating prime numbers.
Requirements:
- Compiler (IDE is advised)
Program goal:
- Calculate primenumbers
- Print them on screen
- Stop if the max is reached (max is entered by user on start) or when a key got hit
- Display number of milliseconds the script took to complete the calculations
Okay, lets start:
Calculate primenumbers:
So how do we calculate them? First a few facts about primenumbers. A primenumber is a number that can only be divided by 1 or itself (to get a round number). That means that 7 is a primenumber, but 9 (3x3) isn't! This also means that every even number is not a primenumber, except 2.
Conclusion: we shouldn't check all numbers to calculate if its a primenumber or not. We should only check the odd numbers, except for 2. So if we print 1 and 2 as primenumbers manually on screen, we can start with checking the number 3 for being prime or not. Than we keep increasing the currently checked number for being prime by 2. We start with 3, than 5, 7, 9, 11 etc.
3 is the first number we start with. If its prime, we can only divide it by 1 and 3, and not by 2. If we divide it by 2, we get 1.5, so its a primenumber! Same for 5, 7 and 11.
So how do we write that in C++? For example we check 11. We start by calculating 11/2, than 11/3. Both don't result in round numbers. So its a prime number...but hey, we only calculated till 11/3, so we forgot to calculate 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10 you might think. But we only have to divide it till the squareroot of 11 or below. I will explain this with the number 16, as thats easier:
16 is not a prime number: (1x16 and 16x1 are not listed, as thats true for every number)
2x8 = 16
4x4 = 16
8x2 = 16
Notice that 2x8 and 8x2 are exactly the same except for the sequence. So in fact we only have to check for 2x8 and 4x4 (4 is the squareroot of 16).
Another thing: for 11, we only have to check for 11/3 and not for 11/2. Because every number we test for being prime or not, is an odd number, so it will never result in a round number if we divide it by an even number. Therefore the number with which we divide should start with 3 and should increase with 2 each time (3, 5, 7, 9, 11).
We start by checking 3 for being prime or not. To check if its prime, we start by dividing it by 3. We keep increasing 'o' by 2, as long as it is smaller or equal to the square root of 3. The square root of 3 is 1.7, so we don't go through the inner while loop at all. 3 is a primenumber.
Same for 5 and 7.
Than we calculate it for 11. The square root of 11 is 3.3, so we loop once through the inner while loop. The percentage character (%) returns the remainder if you divide the first by the second argument. 5%2 = 1, 8%2 = 0, 11%3 = 2. So 11%3 does not equals 0, so we don't stop the loop because its not a prime, but we continue and increase 3 by 2 = 5. 5 is bigger than the square root of 11, so we _do_ quit the loop, lol, and its a prime.
So that way we can search for prime numbers
Print them on screen
We use the cout function for this, and the needed headers and stuff:
Here we add the boolean 'prime' to see if its a primenumber, because we only want primenumbers to be printed on the screen. We also print the numbers 1 and 2 manually as described above.
Stop if the max is reached (max is entered by user on start) or when a key got hit
To get user input, we use the cin function. And to know if a key gets hit, we use the kbhit(); function (conio.h header).
The entered number 'max' will be the maximal number 'i' can get. Except if a key gets hit, it will quit the while loop earlier.
Display number of milliseconds the script took to complete the calculations
Here we use the clock(); function, to get the time in milliseconds. So before we output it, we need to divide it by 1000 to display it as seconds. However, we only calculate the time passed by the actual primenumber calculations, and not the time the user took to enter the desired max (clock() gives the number of milliseconds passed since the start of the application).
Final code:
We want the application to pause before closing, so the user can actually see the number of passed seconds. The system("PAUSE"); function can be used for this, but remember that this is windows only!
Final code for windows (other platforms should just delete the system("PAUSE"); line at the end):
Source code
Executable + Source code (zip)
I hope you understand the theory. If you have any questions, suggestions or improvements, feel free to reply
.
Daevius
PS: To keep the script going without a max, just enter something else than a number
.
PSS: Script update. 'o' now starts with 3 and gets increased by 2. Thanks to _Gabriel_.
Inspired by Kyle Enos's great 2 tutorial threads, I thought about making a tutorial too
Requirements:
- Compiler (IDE is advised)
Program goal:
- Calculate primenumbers
- Print them on screen
- Stop if the max is reached (max is entered by user on start) or when a key got hit
- Display number of milliseconds the script took to complete the calculations
Okay, lets start:
Calculate primenumbers:
So how do we calculate them? First a few facts about primenumbers. A primenumber is a number that can only be divided by 1 or itself (to get a round number). That means that 7 is a primenumber, but 9 (3x3) isn't! This also means that every even number is not a primenumber, except 2.
Conclusion: we shouldn't check all numbers to calculate if its a primenumber or not. We should only check the odd numbers, except for 2. So if we print 1 and 2 as primenumbers manually on screen, we can start with checking the number 3 for being prime or not. Than we keep increasing the currently checked number for being prime by 2. We start with 3, than 5, 7, 9, 11 etc.
3 is the first number we start with. If its prime, we can only divide it by 1 and 3, and not by 2. If we divide it by 2, we get 1.5, so its a primenumber! Same for 5, 7 and 11.
So how do we write that in C++? For example we check 11. We start by calculating 11/2, than 11/3. Both don't result in round numbers. So its a prime number...but hey, we only calculated till 11/3, so we forgot to calculate 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10 you might think. But we only have to divide it till the squareroot of 11 or below. I will explain this with the number 16, as thats easier:
16 is not a prime number: (1x16 and 16x1 are not listed, as thats true for every number)
2x8 = 16
4x4 = 16
8x2 = 16
Notice that 2x8 and 8x2 are exactly the same except for the sequence. So in fact we only have to check for 2x8 and 4x4 (4 is the squareroot of 16).
Another thing: for 11, we only have to check for 11/3 and not for 11/2. Because every number we test for being prime or not, is an odd number, so it will never result in a round number if we divide it by an even number. Therefore the number with which we divide should start with 3 and should increase with 2 each time (3, 5, 7, 9, 11).
Code:
int i = 3, o;
while (i)
{
o = 3;
while (o <= sqrt(i))
{
if (i % o == 0)
{
break;
}
o += 2;
}
i += 2;
}
Same for 5 and 7.
Than we calculate it for 11. The square root of 11 is 3.3, so we loop once through the inner while loop. The percentage character (%) returns the remainder if you divide the first by the second argument. 5%2 = 1, 8%2 = 0, 11%3 = 2. So 11%3 does not equals 0, so we don't stop the loop because its not a prime, but we continue and increase 3 by 2 = 5. 5 is bigger than the square root of 11, so we _do_ quit the loop, lol, and its a prime.
So that way we can search for prime numbers
Print them on screen
We use the cout function for this, and the needed headers and stuff:
Code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int i = 3, o;
bool prime;
cout << "\n1\n2\n";
while (i)
{
prime = true;
o = 3;
while (o <= sqrt(i))
{
if (i % o == 0)
{
prime = false;
break;
}
o += 2;
}
if (prime)
{
cout << i << "\n";
}
i += 2;
}
return 0;
}
Stop if the max is reached (max is entered by user on start) or when a key got hit
To get user input, we use the cin function. And to know if a key gets hit, we use the kbhit(); function (conio.h header).
Code:
#include <iostream>
#include <math.h>
#include <conio.h>
using namespace std;
int main()
{
int i = 3, o, max;
bool prime;
cout << "Maximal: ";
cin >> max;
cout << "\n1\n2\n";
while (i <= max)
{
prime = true;
o = 3;
while (o <= sqrt(i))
{
if (i % o == 0)
{
prime = false;
break;
}
o += 2;
}
if (prime)
{
cout << i << "\n";
}
if (kbhit())
{
break;
}
i += 2;
}
return 0;
}
Display number of milliseconds the script took to complete the calculations
Here we use the clock(); function, to get the time in milliseconds. So before we output it, we need to divide it by 1000 to display it as seconds. However, we only calculate the time passed by the actual primenumber calculations, and not the time the user took to enter the desired max (clock() gives the number of milliseconds passed since the start of the application).
Code:
#include <iostream>
#include <math.h>
#include <conio.h>
using namespace std;
int main()
{
int i = 3, o, max;
bool prime;
double seconds;
cout << "Maximal: ";
cin >> max;
cout << "\n1\n2\n";
seconds = clock();
while (i <= max)
{
prime = true;
o = 3;
while (o <= sqrt(i))
{
if (i % o == 0)
{
prime = false;
break;
}
o += 2;
}
if (prime)
{
cout << i << "\n";
}
if (kbhit())
{
break;
}
i += 2;
}
seconds = clock() - seconds;
cout << "\n" << seconds / 1000 << " seconds" << endl;
return 0;
}
We want the application to pause before closing, so the user can actually see the number of passed seconds. The system("PAUSE"); function can be used for this, but remember that this is windows only!
Final code for windows (other platforms should just delete the system("PAUSE"); line at the end):
Source code
Executable + Source code (zip)
I hope you understand the theory. If you have any questions, suggestions or improvements, feel free to reply
Daevius
PS: To keep the script going without a max, just enter something else than a number
PSS: Script update. 'o' now starts with 3 and gets increased by 2. Thanks to _Gabriel_.
Last edited:

