program stops responding when I run for loop in C - c

Logic: I am trying to loop from 3 to 100 and put all prime numbers in that range in an array. I do this by first putting 2 manually into the array. After that, I loop over all the numbers and if a number is not divisible by all the prime numbers I have added to the array, it is a prime. The logic itself is not really valid in my opinion but this is a homework problem and I need to do it the way the professor wants it to be done.
So I try to loop and it gets to a point and the program just crashes. What am I doing wrong here?
int primeNums_lessThan100[25] = {2}; //25 is the size here because there are only 25 prime numbers under 100.
int primeNums_lessThan100_length = 1;
for(int counter = 3 ; counter < 100 ; counter++)
{
printf("Entered here!\n");
for(int array_idx = 0; array_idx < primeNums_lessThan100_length ; array_idx++)
{
if(counter % primeNums_lessThan100[array_idx] != 0)
{
printf("Entered here, TOO!\n");
primeNums_lessThan100[array_idx+1] = counter;
primeNums_lessThan100_length++;
}
else
{
continue;
}
}
}

You have a basic error in your logic. It's not enough to find out the counter value is coprime with some previously found prime to determine counter is prime itself. You need to test it is coprime with all primes found.
Suppose counter == 9 and you test it against the first item of your 'prime' numbers, which is 2. The result of 9 % 2 is of course 1, which is not equal zero and your program adds 9 to the array as a prime number. It happens even earlier for counter == 4 — first you find out it is divisible by 2 and reiterate the loop to find out in the next step 4 % 3 != 0 and add 4 to 'primes'.
As a further result the array overflows (you put more numbers into it than you expected and declared; actually, you put every natural number to it, because each N greater than 2 is not divisible by (N-1)), which means you eventually write past the end of the array, thus triggering an Undefined Behavior.
That displays also a basic error in the design: you do not check your array_idx against the array size, which might allow you to handle the error in some civilized manner.

the following proposed code:
cleanly compiles
performs the desired functionality
comments in code explain what is being done
note use of size_t for numbers that will never be less than 0
Note that all prior prime values are checked against the testPrime
Note that when a prime is found, it is placed in the next available entry in the array: `primeNums[]
and now, the proposed code:
#include <stdio.h> // puts(), printf()
// eliminate ''magic' numbers by giving them meaningful names
//25 is the size here because there are only 25 prime numbers under 100
#define MAX_PRIMES 25
#define TEST_LIMIT 100
int main( void )
{
// declare prime number array and init to 0
int primeNums[ MAX_PRIMES ] = {0};
// pre-set first prime number
primeNums[0] = 2;
// init number of primes found
size_t primeCount = 1;
// test all values of interest
for( int testPrime = 3 ; testPrime < TEST_LIMIT ; testPrime++ )
{
// init 'prime' indicator, 1 means value is prime
size_t Prime = 1;
for( size_t prime_idx = 0; prime_idx < MAX_PRIMES; prime_idx++ )
{
// check that array of prime values contains a valid prime
if( primeNums[ prime_idx ] )
{
if( testPrime % primeNums[ prime_idx ] == 0 )
{
// indicate not a prime number
Prime = 0;
}
}
else
{ // else, all previously found prime numbers checked
break;
} // end if
} // end for each prime already found
if( Prime )
{ // then test number was prime
// update the array of primes
primeNums[ primeCount ] = testPrime;
// update the count of primes found
primeCount++;
}
}
// display the found primes
for( size_t i = 0; i < primeCount; i++ )
{
printf( "%d, ", primeNums[i] );
}
// assure the data gets displayed on the terminal before the program exits
puts( "" );
}
a run of the proposed code results in:
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,

Related

How to iterate over numbers in C

I've gotta count how many times a certain digit is repeated in each number in a range. For example, in the numbers between 0 and 20, there is only one occurrence of 1 being repeated twice (11). I originally did this by converting the int to a str and iterating over it, but I would like to be able to solve this in an arithmetic way. Any ideas?
here is a general solution that you can use , your problem didn't contain much information so I assumed that you want to count the number of repeating of each digit in each number.
so what I did is like hashing where the digits in each number will never cross the value 9 , so they are from 0 to 9 so I made that hash table called arr, so what I did is to come to every single digit in number and increment the position of that digit in arr
for example , number 554 will cause arr[5]++; twice and arr[4]++; only once , simple idea of using hash tables.
and then at the end I iterate over the hash array printing the number of occurrence of each digit in each number.
and here is the code :
#include <stdio.h>
#include <math.h>
int main()
{
int arr[6] = {5555, 12112, 14, -3223, 44, 10001};
int tempArr[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for (int i = 0; i < 6; i++) {
int temp1 = arr[i];
// get the number of occurrences of each digit in each number
do{
tempArr[(abs(temp1) % 10)]++;
temp1 /= 10;
}while(temp1 != 0);
// loop over the array to know how many times each digit occurred
printf("the number of occurrences in number called %d\n", arr[i]);
for (int j = 0; j < 10; j++) {
if(tempArr[j] > 1)
printf("number %d occurred %d times\n", j, tempArr[j]);
// resetting that position of the array
tempArr[j] = 0;
}
}
return 0;
}
and here is the output :
the number of occurrences in number called 5555
number 5 occurred 4 times
the number of occurrences in number called 12112
number 1 occurred 3 times
number 2 occurred 2 times
the number of occurrences in number called 14
the number of occurrences in number called -3223
number 2 occurred 2 times
number 3 occurred 2 times
the number of occurrences in number called 44
number 4 occurred 2 times
the number of occurrences in number called 10001
number 0 occurred 3 times
number 1 occurred 2 times
You can divide your number multiple times by 10:
int number = 72;
int rest;
while(number)
{
rest = number % 10;
printf("%d\n", rest);
number /= 10;
}
Here rest contains '2' and then '7'
how many times a certain digit is repeated in each number in a range.
Pseudo code*1
Get the range: imin, imax (any int pair where imin <= imax)
Get the digit: digit 0 to 9
Iterate m from imin to imax, inclusive
.... Print m
.... Set digit_count = 0
.... Repeat
....... Last digit ld of m is abs(m%10).
....... If ld == digit, increment digit_count.
........ Divide m by 10
.... Until m == 0
.... Print digit_count
Done
*1 As OP did not provide code, seemed best to not provide a code answer.
Riffing on the answer provided by #Abdo Salm presented only to demonstrate a slightly alternative approach. All credit to Abdo.
EDIT: Going beyond single, arbitrary numbers to generating ascending contiguous sequence of numbers to be evaluated.
#include <stdio.h>
#include <string.h>
#include <limits.h>
void process( int n, int cnts[] ) {
// count occurences of each digit (right to left)
while( n )
cnts[ abs(n % 10) ]++, n /= 10;
}
void report( int cnts[], int thresh ) {
char *sep = "";
for( int j = 0; j < 10; j++ )
if( cnts[ j ] > thresh )
printf( "%s%dx%d", sep, cnts[ j ], j ), sep = ", ";
if( !*sep )
printf( "no digit occurred multiple times" );
putchar( '\n' );
}
int main() {
#ifndef PROVE
int tests[] = {
0, 11, 121, 5555, 12112, 14,
-3223, 44, 1223334444,
INT_MIN, INT_MAX,
};
// proof of concept: run through multiple arbitrary test values
for( int i = 0; i < sizeof tests/sizeof tests[0]; i++ ) {
// counter for each digit, all init'd to zero
int cnts[ 10 ];
memset( cnts, 0, sizeof cnts );
process( tests[ i ], cnts );
// report only digits appearing multiple times
printf( "%11d: ", tests[ i ] );
report( cnts, 1 );
}
#else // with "ranges" instead of arbitrary test cases
int ranges[][2] = {
{ 0, 10, },
{ 0, 22, },
{ 110, 133, },
{ 447, 448, },
};
for( int r = 0; r < sizeof ranges/sizeof ranges[0]; r++ ) {
int metacnts[10];
memset( metacnts, 0, sizeof metacnts );
for( int i = ranges[r][0]; i <= ranges[r][1]; i++ ) {
int cnts[ 10 ];
memset( cnts, 0, sizeof cnts );
process( i, cnts );
for( int j = 0; j < 10; j++ )
if( cnts[ j ] > 1 )
metacnts[ j ]++;
}
// report only digits appearing multiple times in numbers between min & max
printf( "Range %3d-%3d (incl) ", ranges[r][0], ranges[r][1] );
report( metacnts, 0 );
}
#endif
return 0;
}
/*
Output from arbitrary sequence:
0: no digit occurred multiple times
11: 2x1
121: 2x1
5555: 4x5
12112: 3x1, 2x2
14: no digit occurred multiple times
-3223: 2x2, 2x3
44: 2x4
1223334444: 2x2, 3x3, 4x4
-2147483648: 3x4, 2x8
2147483647: 3x4, 2x7
Output from arbitrary ranges:
Range 0- 10 (incl) no digit occurred multiple times
Range 0- 22 (incl) 1x1, 1x2
Range 110-133 (incl) 12x1, 1x2, 1x3
Range 447-448 (incl) 2x4
*/

How can I print a table if the format below?

I've been racking my brain on how I would be able to print my array in the format below(image)
I have done the necessary calculations in my code to have an array for the numbers {18,23,22,21...} but I'm trying to figure out a way to format them so they are under the corresponding years.
The furthest left column are the first 3 numbers of a year and the top row is the last number.
For example if this data was calculated for year starting in 2010, the numbers would start under the 0 column, and so on.
So far I could only come up with hard-coding the spaces so everything lines up, but as the year is a user input I can't figure out how to automatically have the data start under the corresponding year. I appreciate any ideas you can offer.
printf(" 0 1 2 3 4 5 6 7 8 9\n");
printf("%c%c%c\n", year1[0], year1[1], year1[2]);
printf("%c%c%c\n", year2[0], year2[1], year2[2]);
printf("%c%c%c\n", year3[0], year3[1], year3[2]);
where the indexed arrays would print the first 3 numbers of the year similar to the picture.
Since another answer has already provided a full solution, I will now provide my own full solution.
The advantage of my solution is that less if checks are necessary, because I have placed the code which jumps several columns outside the main loop. That way, it is not necessary to constantly check inside the main loop whether we must jump several columns. Also, I make more use of the control flow of the program, so that in the main loop, the only conditions that I must check for are
whether the end of the line has been reached, and
whether the end of the array has been reached.
However, the disadvantage of my solution is that my two nested for loops are harder to understand, because they have a non-standard structure.
#include <stdio.h>
void print_table( int start_year, int values[], int num_values )
{
int col;
int written = 0;
//don't print anything if array is empty
if ( num_values <= 0 )
return;
//calculate quotient and remainder of dividing
//start_year by 10
int quotient = start_year / 10;
int remainder = start_year % 10;
//print header
printf(" 0 1 2 3 4 5 6 7 8 9\n");
//prepare first line for data
printf( "%4d", quotient );
for ( col = 0; col < remainder; col++ )
{
printf( " " );
}
//process one row per loop iteration
for ( int row = 1; ; row++ )
{
//process one column per loop iteration
for ( ; col < 10; col++ )
{
printf( " %3d", values[written++] );
//check whether we have reached the end of the array
if ( written == num_values )
{
putchar( '\n' );
return;
}
}
//prepare next line for data
printf( "\n%4d", quotient + row );
col = 0;
}
}
int main( void )
{
int arr[] = {
18, 23, 22, 21, 20,
18, 24, 23, 22, 20, 19, 18, 24, 22, 21,
20, 19, 24, 23, 22
};
print_table( 2015, arr, sizeof arr / sizeof *arr );
}
This program has the following output:
0 1 2 3 4 5 6 7 8 9
201 18 23 22 21 20
202 18 24 23 22 20 19 18 24 22 21
203 20 19 24 23 22
Highlights of the code below:
The year is broken into two parts using division and modulo operators. The variable blanks, which is set to the last digit of the year, is the number of columns that need to be skipped on the first line. The variable row is the upper digits of the year, and is used as the row label.
The for loop goes through each element of the array.
The array element is printed near the middle of the body of the loop.
Before printing the array element:
When a new row is being started (col == 0), the row label is printed
When the blanks need to be displayed (blanks > 0):
print the necessary spaces
update the column number so that col reflects the current location on the line
set blanks to 0, so that this only happens once
After printing the array element:
Update the column number
When the last column is reached, output a newline and start a new row
Here's the code:
#include <stdio.h>
void showTable(int year, int array[], int length)
{
// print the column headers
printf(" 0 1 2 3 4 5 6 7 8 9\n");
// initialize some variables
int blanks = year % 10; // number of entries to skip on the first row
int row = year / 10; // upper digits of the year, used as the row label
int col = 0; // column number 0 to 9
// loop through the elements of the array
for (int i = 0; i < length; i++)
{
// print the year prefix when the column number is 0
if (col == 0)
printf("%3d", row);
// print blank spaces to reach the starting column on the first line
// this is only done once
if (blanks > 0)
{
printf("%*s", blanks * 4, "");
col += blanks;
blanks = 0;
}
// print a number from the array
printf(" %3d", array[i]);
// update the column, if we've reached the last column, start a new row
col++;
if (col > 9) {
printf("\n");
col = 0;
row++;
}
}
// output a final newline, if needed
if (col != 0)
putchar('\n');
}
int main(void)
{
int year = 2015;
int values[] = { 18, 23, 22, 21, 20, 18, 24, 23, 22, 20,
19, 18, 24, 22, 21, 20, 19, 24, 23, 22 };
showTable(year, values, sizeof(values) / sizeof(values[0]));
}
it is not correct code, but can give educational idea how to solve your task
int i = 2010;
while ()
{
if (input_year < i);
printf(" ");
else
printf("%d", calculated_data);
i++;
}
and please show your code, if you want some more ideas how to improve your code

How to increment numbers by five in a for loop

Hi so I am using C code and trying to create a table where the number gets incremented in multiples of 5 starting from 1 to 5 to 10 to... all the way until the user's input. What I've gotten so far is that it starts at 1 and then increases the number by 5 like 1 to 6 to 11 to 16... until it gets to where it can't increase the number by 5 anymore without going above the user's input. Could someone help me set up the for loop better?
Here's the segment of my code I'm talking about:
else //run this statement if the user inputs a number greater than 14
{
printf("Number Approximation1 Approximation2\n-----------------------------------------------------\n"); //prints the header for second table
for ( i = 1; i <= n; i += 5 )
{
printf("%d %e %e\n", i, stirling1( i ), stirling2( i )); //calls functions to input approximate factorials
}
}
So with this code if I input n as 28, I get i to increment from 1 to 6 to 11 to 16 to 21 to 26.
What I want the code to do if I input n as 28 is increment i from 1 to 5 to 10 to 15 to 20 to 25 to 28.
Thanks in advance!
Try this:
{
printf("Number Approximation1 Approximation2\n-----------------------------------------------------\n"); //prints the header for second table
printf("%d %e %e\n", i, stirling1( 1 ), stirling2( 1 ));
for ( i = 5; i <= n; i += 5 )
{
printf("%d %e %e\n", i, stirling1( i ), stirling2( i )); //calls functions to input approximate factorials
}
}
This will print values for 1, 5, 10, 15, 20... and so on
Note that, besides an extra line of code, its faster than adding an "if" inside the loop.
I added two if statements which would help you deal with the special cases of having statements printed at i = 1 and i = n besides having the statement printed every 5.
else //run this statement if the user inputs a number greater than 14
{
printf("Number Approximation1 Approximation2\n-----------------------------------------------------\n"); //prints the header for second table
for ( i = 1; i <= n; i += 5 )
{
printf("%d %e %e\n", i, stirling1( i ), stirling2( i )); //calls functions to input approximate factorials
if (i == 1){
//when it iterates at the end of this loop, i = 5.
//In your example, you will get i from 1 to 5 to 10 up to 25 etc.
i = 0;
}
if ( (i + 5) > n){
// for the next loop, it will check if i will exceed n on the next increment.
// you do not want this to happen without printing for n = i.
//In your case if n = 28, then i will be set to 23, which will then increment to 28.
i = n - 5;
}
}
}
There are probably other more elegant ways of achieving this, but this is just a simple example of what you could try.

Sieve Of Erastothenes BSP C implementation doesn't find all primes

I have a BSP implementation in C for the Sieve Of Erastothenes, see the code below.
When executed with ./bspsieve 2 100 it however gives the following output:
"It took : 0.000045 seconds for proc 0 out of 2.
23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,"
for ./bspsieve 1 100 it gives the same, i.e:
"./bspsieve 1 100
It took : 0.000022 seconds for proc 0 out of 1.
23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,"
For ./bspsieve 8 100 (so using 8 processors) it gives a segmentation fault.
i.e
"./bspsieve 8 100
It took : 0.000146 seconds for proc 0 out of 8.
Segmentation fault (core dumped)"
This means that my bounds aren't okay I think?
It fails to find the first primes! I can't find my fault (really inexperienced with C). Except this, are there other improvements to my code you guys can suggest? The algorithm doesn't need to be fast, but any improvement in understandability and readability is welcome.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mcbsp.h>
/*
Note: To compile, this file has to be in the same folder as mcbsp.h and you need the 2 following commands:
gcc -Iinclude/ -pthread -c -o bspsieve.o bspsieve.c
gcc -o bspsieve bspsieve.o lib/libmcbsp1.1.0.a -lpthread -lrt
*/
int procs;
int upperbound;
int *primes;
//SPMD function
void bspSieve(){
bsp_begin(procs);
int p = bsp_nprocs(); // p = number of procs obtained
int s = bsp_pid(); // s = proc number
float blocksize; // block size to be used, note last proc has a different size!
if( s != p-1){
blocksize = ceil(upperbound/p);
} else {
blocksize = upperbound - (p-1)*ceil(upperbound/p);
}
// Initialize start time and end time, set start time to now.
double start_time,end_time;
start_time = bsp_time();
// Create vector that has block of candidates
int *blockvector;
blockvector = (int *)malloc(blocksize*sizeof(int));
int q;
for(q = 0; q<blocksize; q++){
//List contains the integers from s*blocksize till blocksize + s*blocksize
blockvector[q] = q + s*blocksize;
}
//We neglect the first 2 'primes' in processor 0.
if(s == 0){
blockvector[0] = 0;
blockvector[1] = 0;
}
// We are using the block distribution. We assume that n is large enough to
// assure that n/p is larger than sqrt(n). This means that we will always find the
// sieving prime in the first block, and so have to broadcast from the first
// processor to the others.
long sieving_prime;
int i;
bsp_push_reg( &sieving_prime,sizeof(long) );
bsp_sync();
for(i = 2; i * i < upperbound; i++) {
//Part 1: if first processor, get the newest sieving prime, broadcast. Search for newest prime starting from i.
if(s == 0){
int findPrimeNb;
for(findPrimeNb = i; findPrimeNb < blocksize; findPrimeNb++) {
if( blockvector[findPrimeNb] != 0) {
sieving_prime = blockvector[findPrimeNb];
//broadcast
int procNb;
for(procNb = 0; procNb < p; ++procNb){
bsp_put(procNb, &sieving_prime,&sieving_prime,0,sizeof(long));
}
break;
}
}
}
bsp_sync();
//Part 2: Sieve using the sieving prime
int sievingNb;
for(sievingNb = 0; sievingNb < blocksize; sievingNb++){
//check if element is multiple of sieving prime, if so, pcross out (put to zero)
if( blockvector[sievingNb] % sieving_prime == 0){
blockvector[sievingNb] = 0;
}
}
}
//part 3: get local primes to central area
int transferNb;
long transferPrime;
for(transferNb = 0; transferNb < blocksize; transferNb++){
transferPrime = blockvector[transferNb];
primes[transferPrime] = transferPrime;
}
// take the end time.
end_time = bsp_time();
//Print amount of taken time, only processor 0 has to do this.
if( s == 0 ){
printf("It took : %.6lf seconds for proc %d out of %d. \n", end_time-start_time, bsp_pid(), bsp_nprocs());
fflush(stdout);
}
bsp_pop_reg(&sieving_prime);
bsp_end();
}
int main(int argc, char **argv){
if(argc != 3) {
printf( "Usage: %s <proc count> <upper bound> <n", argv[ 0 ] );
exit(1);
}
//retrieve parameters
procs = atoi( argv[ 1 ] );
upperbound = atoi( argv[ 2 ] );
primes = (int *)malloc(upperbound*sizeof(int));
// init and call parallel part
bsp_init(bspSieve, argc, argv);
bspSieve();
//Print all non zeros of candidates, these are the primes.
// Primes only go to p*p <= n
int i;
for(i = 0; i < upperbound; i++) {
if(primes[i] > 0) {
printf("%d, ",primes[i]);
fflush(stdout);
}
}
return 0;
}
Troubles may come from
blockvector[q] = q + s*blocksize;
As long as blocksize is equal to ceil(upperbound/p) on all processus, there is no problem. Since 1 and 2 are divisor of 100, your program works well.
As you wrote in your code, it is not always the case...It is not true on the last processus when calling ./bspsieve 8 100. Some values in blockvector are above 100, and a segmentation fault is likely to appear when writting in the prime array.
A way to correct this behaviour is :
blockvector[q] = q + s*ceil(upperbound/p);
(store ceil(...) to run faster.)
It might also be better to zero the prime array before using it.
I did not check wheather it works...Try it !
Bye,
Francis
Some possible issues are noted below. Note that if you had supplied a standalone, compilable example (as an external download for example) it would make it easier for someone unfamiliar with the BSP library to help you. Also noting the specific library would help (assuming it is MulticoreBSP).
I believe you are incorrectly dividing the number by itself. For example try manually tracing the first case:
i = 2
so sieving_prime = 2
2 % 2 == 0 so blockvector[2] = 0 (incorrectly saying 2 is not prime)
This issue is why you are only outputting primes starting at 23. You are looping 8 times (for (i=2; i*i<100..., 2..9). For these loops you start at the primes 2, 3, 5, 7, 11, 13, 17, 19 which incorrectly eliminates each them leaving 23 as the first prime output.
For upperbound/p when both variables are integers the division result will be an integer so that ceil(upperbound/p) probably doesn't do what you think it does. For example ceil(100/8) == 12 not 13. Cast the numbers to float if you wish the division result to be a floating point.
Related to this your last block is not being populated with numbers correctly when the last block is a different size (i.e., procs does not evenly divide upperbound). For example in the case of bspsieve 8 100 your last block starts at 112 instead of 90.
This last issue is most likely the cause of your segmentation fault since a value of 112 will overflow your primes[] array.
Fixing these issues 'should' fix the incorrect output and the crash. If you are still getting incorrect output I would add liberal printf() calls until you can see where the code differs from what it should be. I would also start testing with 1 processor first and increment this one at a time to confirm correct operation. Also test with different upper bounds.

for loop C work weird?

I have a problem with for loop in C.
The purpose of the program is to find prime numbers in known quantity k.
Here is my program:
unsigned int i, k, j;
unsigned long int prime;
int _tmain(int argc, _TCHAR* argv[]) {
printf("How many prime numbers do you want to print out in order? "); scanf_s("%u", &k);
printf("%u fist prime numbers are: ", k);
i = 1;
prime = 2;
while (i <= k)
{
for (j = 2; j <= prime; j++)
{
if (prime % j == 0)
{
if (j == prime && prime != 2)
{
printf("%lu, ", prime);
i++;
}
prime++;
j = 2;
}
}
}
_getch();
return 0;
}
And when I run the program, it returns infinite sequence of numbers. But if I adds "else j++;" like this:
for (j = 2; j <= prime; j++)
{
if (prime % j == 0)
{
if (j == prime && prime != 2)
{
printf("%lu, ", prime);
i++;
}
prime++;
j = 2;
}
else j++;
}
Then the program will work out properly. I think this is kinda weird and can't explain why?
Thanks in advance (and sorry for my bad English).
As I mentioned in comments, the problem was caused by your having no "break" in the for-loop to cause it to return to the outer while loop when you detected a valid divisor.
This was compounded by your poor use of variable names confusing you - your original code appears to be confused about what "j" and "prime" are.
Here I've refactored your code to be cleaner and give a significant performance increase for large prime searches:
#include <stdio.h>
#define FALSE (0)
#define TRUE (!(FALSE))
int main()
{
int numPrimes = 0;
int candidate, divisor;
int isPrime;
printf("How many prime numbers do you want to print out in order? ");
scanf("%u", &numPrimes);
printf("\n%u first prime numbers are:\n", numPrimes);
if (numPrimes > 0) {
printf("2, ");
--numPrimes;
}
// we only need to test odd numbers.
for (candidate = 3; numPrimes > 0; candidate += 2) {
// N / (N/2) + 1 is always < 1, so we only have to test half the values.
// we also only need to test odd divisors
isPrime = TRUE;
for (divisor = 3; divisor <= candidate / 2; ++divisor) {
// it's not prime if testNumber divides in
if (candidate % divisor == 0) {
isPrime = FALSE;
break;
}
}
if (isPrime) {
printf("%lu, ", candidate);
--numPrimes;
}
}
printf("\n");
return 0;
}
Live demo here: http://ideone.com/yrUPBy
Which gladly tells me
How many prime numbers do you want to print out in order?
1000 first prime numbers are:
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, 101, 103, 107, 109, 113, 127,
...
7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841,
7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
Your loop has j <= prime as the end condition, meaning the last value of j will be equal to prime. In that case (prime % j == 0) will always be true.
When you add the extra j++ you're skipping half the values of j which accidentally skips past the problem. The program still isn't working correctly.
When the program prints the prime 3, the variables have the following values:
i = 1
j = 3
prime = 3
Then you increment i and prime, and set j = 2, so it's:
i = 2
j = 2
prime = 4
Now you return to the top of the loop, which does j++:
i = 2
j = 3
prime = 4
Since j <= prime, the loop continues. Since prime % j is not 0, it skips the body of that if, and returns to the top of the loop, which increments j again:
i =2
j = 4
prime = 4
This time prime % j == 0, so it prints prime, even though it's not actually a prime number.
This keeps happening for every value of prime.
When you add j++ to the else clause, it causes j to be incremented twice in the failing case. So it goes from 3 to 5, and never makes it to the case where j == prime and it prints the number. Then j <= prime fails, so the for loop terminates.

Resources