Reputation: 844
How come do I get a message "Command terminated" when I try to input a large number (around 10 million)? The program displays whether the number is a prime or not.
See code below:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int main ( int argc, char *argv[] )
{
unsigned long long number;
bool prime ( unsigned long long );
printf ("Enter a positive integer greater than 1: ");
scanf ("%llu", &number );
prime( number ) ?
printf ( "%llu is a prime.\n", number ):
printf ( "%llu is not a prime.\n", number);
return EXIT_SUCCESS;
}
bool prime ( unsigned long long number )
{
unsigned long long i, j;
bool isPrime[number + 1];
for ( i = 2; i <= number; i++ )
isPrime[i] = true;
for ( i = 2; i <= number - 1; i++ )
for ( j = 1; i*j <= number; j++ )
isPrime[i*j] = false;
return isPrime[number];
}
Upvotes: 1
Views: 514
Reputation: 46425
The problem is that you attempt to create an array isPrime
on the stack that is larger than the available memory. You should create it on the heap instead, using
bool *isPrime;
isPrime = malloc((number + 1) * sizeof *isPrime);
do this only once obviously, not for every call to the function prime
Notice also that if you just want to know if a number is prime, you only need to search as far as the square root of the number for a factor - and if you find a factor you are done. This makes the size of the array you have to create much more manageable - but it does involve some changes to your algorithm.
afterthought you have a problem in the logic that determines what is a prime number - your inner loop starts with j=1
which means that even prime numbers will be marked as non-prime. The following is "slightly improved" code - although there's more you could do to make it much better:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
int main ( int argc, char *argv[] )
{
unsigned long long number;
bool prime ( unsigned long long );
printf ("Enter a positive integer greater than 1: ");
scanf ("%llu", &number );
prime( number ) ?
printf ( "%llu is a prime.\n", number ):
printf ( "%llu is not a prime.\n", number);
return EXIT_SUCCESS;
}
bool prime ( unsigned long long number )
{
unsigned long long i, j, sq;
bool *isPrime;
sq = ceil(sqrt(number));
isPrime = malloc((sq + 1)*sizeof *isPrime);
// generate primes up to the square root of the number
for ( i = 2; i <= sq; i++ )
isPrime[i] = true;
for ( i = 2; i < sq; i++ ) {
// only need to mark multiples if this is a prime:
if(isPrime[i]) {
// start this loop at 2, not 1!
for ( j = 2; i*j <= sq; j++ ) {
isPrime[i*j] = false;
}
}
}
for ( i = 1; i < sq; i++)
{
if (isPrime[i] && number%i==0) return false;
}
return true;
}
Basic testing:
gcc -Wall
generates no errors / warnings
104729
is a prime (it is); code doesn't crash with an input of 10000001
(not a prime).
Upvotes: 3