Command terminated when inputting large number - c

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];
}

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).

Related

Any idea on why this program is returning that 987 is a prime number (when it is not a prime number)?

I think the problem is with the for-loop but I cannot understand it. This is an assignment in school that I only should use for-loops and if statements to solve!
#include <stdio.h>
int is_prime(int n){
for (int i=2;i<n;i++){
if (n%i!=0){
return 1;
}
else{
return 0;
};
};
}
int main(void){
printf("%d\n", is_prime(11)); // 11 is a prime. Should print 1.
printf("%d\n", is_prime(383)); // 383 is a prime. Should print 1.
printf("%d\n", is_prime(987)); // 987 is not a prime. Should print 0.
}
For starters the null statement after the if statement and the for loop itself
for (int i=2;i<n;i++){
if (n%i!=0){
return 1;
}
else{
return 0;
};
^^^
};
^^^
is redundant.
Due to the if statement the for loop is interrupted as soon as either n % i is not equal to 0 or is equal to 0. So in general the behavior of the function does not depend on whether the passed number is prime or not prime.
If you will move the return statement
return 1;
outside the loop as others advised nevertheless the function will be still incorrect. It will show that 0 and 1 are prime numbers while they are not.
Also the condition of the loop makes the loop inefficient at least because it is clear before entering the loop that any even number except 2 is not a prime number.
Pay attention to that the function parameter should have unsigned integer type.
The function can be defined the following way
#include <stdio.h>
int is_prime( unsigned long long int n )
{
int prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned long long int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main(void)
{
printf( "%d\n", is_prime( 11 ) );
printf( "%d\n", is_prime( 383 ) );
printf( "%d\n", is_prime( 987 ) );
return 0;
}
The program output is
1
1
0
The problem is return 1 inside the loop. When you find one i that is not a factor of n, you assume n to be prime. But you have to ensure that all i are not a factor of prime, so the return 1 must be placed after the loop. However, that would cause numbers < 2 to be considered prime, as they do not enter the loop at all. Therefore, you also have to add an additional if at the beginning.
By the way: Every divisor of n (expect n itself) must be <= sqrt(n), therefore you can speed up your function quite a bit.
#include <math.h>
int is_prime(int n) {
if (n < 2)
return 0;
int max_divisor = sqrt(n);
for (int i = 2; i <= max_divisor; i++) {
if (n % i == 0)
return 0;
}
return 1;
}
Problem: return statement
return 1;
}
else{
return 0;
It causes the loop to exit then and there. In your case too, it exits as soon as the first '1' is achieved.
Solution: Instead you should try to store the values in a variable and compare with '1' or '0' at the end of loop

Long number prime detection using Multithreading in C

Problem Statement: To detect whether a long integer number is a prime or not.
My Logic:
The idea is to iterate from 0 to sqrt(n). If no divisor was found between 0 to sqrt(n) then I can conclude that the number is prime and a non-prime otherwise.
Since, this needs to be multi-threaded I created a thread function called void* PrimeDetecter(void* param);. In this thread function I will iterate from startIndex to endIndex and if there was a divisor then quit the thread and write the value 1 to state true to the address of the variable isNum1Prime which is set to 0 by default.
Therefore, in the main function I need to send the number which will be checked, its start index and end index to the thread when creating the thread. So my structure will contain long int number, startIndex, endIndex, *divisor and int isPrime.
Then I create an array of size 10 of type NumberPrime because there are 10 threads and hence divide the iteration equally.
I printed the distribution of index among the threads and that works fine. Then I just create the threads and send all these elements to the thread to check whether the number is prime or not.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#include <pthread.h>
#define MAX_NUM_THREADS 10 // Exercise 1: Not more than 10 threads can run at a time for example.
struct NumberPrime
{
long int number, startIndex, endIndex, *divisor;
int *isPrime;
};
void *PrimeDetector(void *param)
{
struct NumberPrime parameters = *(struct NumberPrime *)param;
for (long int i = parameters.startIndex; i < parameters.endIndex; i++)
{
if (i == 0 || i == 1)
{
break;
}
else
{
if ((parameters.number % i) == 0) // if the divisor is detected then number is not a prime
{
*(parameters.divisor) = i;
*(parameters.isPrime) = 1; // change the value to true
pthread_exit(0); // exit the thread function
}
}
}
}
int main(int argc, char *argv[])
{
long int number1 = 12340000, number2 = 128;
struct NumberPrime primeData1[MAX_NUM_THREADS];
int isNum1Prime = 0; // false
long int number1Divisor = 0;
long int numberSquareRoot1 = (long int)(sqrt(number1)); // get the square root of number1
for (int i = 0; i < MAX_NUM_THREADS; i++)
{
primeData1[i].number = number1;
primeData1[i].isPrime = &isNum1Prime;
primeData1[i].divisor = &number1Divisor;
primeData1[i].startIndex = i * numberSquareRoot1 / MAX_NUM_THREADS;
primeData1[i].endIndex = ((i + 1) * numberSquareRoot1) / MAX_NUM_THREADS;
}
pthread_t primeDetectorThread1[MAX_NUM_THREADS];
int count = 0;
for (int i = 0; i < MAX_NUM_THREADS; i++)
{
if (isNum1Prime == 1)
{
pthread_cancel(primeDetectorThread1[i]);
break;
}
else
{
pthread_create(&primeDetectorThread1[i], NULL, &PrimeDetector, &primeData1[i]);
count++;
}
}
for (int i = 0; i < count; i++)
{
pthread_join(primeDetectorThread1[i], NULL);
}
isNum1Prime == 1 ? printf("Number 1 is prime.\n") : printf("Number 1 is not prime and divisible by %ld\n", number1Divisor);
return EXIT_SUCCESS;
}
The expected output is that the number is not a prime. But no matter what number I choose I always get that the number is prime.
The line if ((parameters.number % i) == 0) tests whether a number is divisible by i. If it is divisible, the number is not prime, but your code goes on to set *(parameters.isPrime) = 1; and end the thread.

Finding the n-th prime number that is palindrome in base K

I recently asked a question about finding whether a number is palindrome in base K or not and I get my answer.
My Recent Question
Now I have a more complicated question, We will get two numbers n and k, and we must find the n-th prime number that is palindrome in base K.
For example if we get 8 and 10, we have 2 3 5 7 11 101 131 151 which are palindrome and prime and so the answer is 151. Another example is 4 2 we have 3 5 7 17 respectively 11 101 111 10001 in base 2 which are prime and palindrome in base so the answer is 17.
n and k are given such that the answer is at most, 1E7.
I submit my program in a judge system and It gave wrong answer in some cases and also Time Limit error in one case. I don't know which part of my algorithm is wrong and what part of it is not optimised.
Note that I am not allowed to use array,vector and strings and also I cannot use libraries more than stdio.h and math.h. It is my program, Can anyone find any problems in it: (I defined intPow because the pow function in math, gives a float and sometime it causes problems)
#include <stdio.h>
#include <math.h>
int primeCheck ( int n);
int palindrome ( int n,int base);
int digitCountBase (int n , int base);
int intPow (int a , int b);
int main()
{
int n;
int base;
scanf("%d %d",&n,&base);
int counter = 0;
int i =2;
int firstRound =1;
while (counter!=n)
{
if (primeCheck(i))
{
if (palindrome (i,base))
{
counter++;
}
}
if (counter ==n)
{
break;
}
if (firstRound)
{
i++;
firstRound=0;
}
else{i+=2;}
}
printf("%d",i);
return 0;
}
int primeCheck ( int n)
{
if (n<2)
{
return 0;
}
if (n==4)
{
return 0;
}
else if (n<=5)
{
return 1;
}
if (n%2 ==0 || n%3 ==0 || n% 5 ==0)
{
return 0;
}
int i =5;
int limit = sqrt(n)+2;
for (int i =5;i<=limit;i+=6)
{
if (n%i==0||n%(i+2)==0)
{
return 0;
}
}
return 1;
}
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
while (n>0&& digitCount >0)
{
if (n%base != (n/power)&&digitCount!=1)
{
isTrue =0;
return 0;
}
n = n- power;
n=n/base;
power = power /base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
int digitCountBase (int n , int base)
{
int digits=0;
while (n)
{
digits++;
n = n / base;
}
return digits;
}
int intPow (int a , int b)
{
int result = 1;
for (int i=1;i<=b;i++)
{
result = result * a;
}
return result;
}
Solution: change palindrome to
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
int original = n;
while (n>0&& digitCount >0)
{
if (n%base != (original/power) % base &&digitCount!=1)
{
isTrue =0;
return 0;
}
n=n/base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
How did I find the error:
You are doing only 2 things, primality testing and palindrome testing, so makes sense to check if these are working fine.
Primality testing is easy, count primes from 1 to 10^7 and compare to known values on google. In this case, this works
To test palindrome, pick a working solution from the internet (even if you canĀ“t submit their solution that uses arrays/strings, you can test with them!). Then iterate from 1 to 10^7 in a certain base and check that both functions return the same.
Testing with base 3, quickly saw that 56 was not giving same output. And the incorrect one was yours.
Then its a matter of fixing your function, which you now know which one is the problem and even have an example of where its not working

C binary program for prime numbers does not want to run

I've a problem at the execution of my program.
I compile it with gcc using: gcc -std=c89 -Wall -Wextra -lm main.c.
Same problem with clang and I didn't try it with tcc yet but I will when the program will be finished.
I would like it to be compilable with a c89 compiler, this explains some of my choices. I've no error at the compilation but a problem at the execution.
Like what's written in some of my comments in my code, at the execution normally, I would have an error because of a division by 0 (with the k variable) but I think I have an error in the "do...while" loop (because the rest of my function is tested), and before the by k division.
I took some hours to debug (especially with gdb (-g option add to the compilation command and run -v in gdb) but I'm still blocked.
/*librairies*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*main function*/
int main(){
int N, b, i, j, h, k;
int *t; /*pointer which will become an array (see in another after comment)*/
float l, m, a;
k = 0; /*Problem with k because we will see later an error*/
printf("Your number : ");
scanf("%d", &N);
if (N>1){
a = sqrt(N);
b = a; /*we convert float into int and it rounds under, normal*/
t = malloc(N * sizeof(int)); /*manual dynamic memory allocation for the array to respect C89*/
if (t==NULL){ /*t is null when you have not enough ram for a too big value for N*/
exit(0);
}
for (i=1;i<N;i++){ /*function to fill the array with 2,3..N*/
j = i + 1;
h = i - 1;
t[h] = j;
}
do{
if (t[k]==0){
k = k + 1;
} else{
for (i=1;i<N;i++){ /*problem nearby, because the division by 0 error does not come know at the execution = 0*/
h = i - 1;
if (t[h]!=0){
l = (float)t[h] / (float)k; /*It's going to be a problem because in the first loop, k = 0*/
m = l - (int)l;
if (m==0.0f){
t[h] = 0;
}
}
}
}
} while (k<b);
h = 0;
for (i=1;i<N;i++){
h = i - 1;
printf("%d\n", t[h]); /*printf to test before continuing the program*/
}
} else{
printf("Your number is not valid\n");
}
return 0;
}
Info: This program is just a personnal project to illustrate for me a math course I had (about prime numbers, and for know with the problem solved and the k problem solved, it should display:
Your number: N /*N is a valid (positive integer) stdin input*/
0 /*and 0 until the k<b prime values are passed but I will make them to be displayed*/
a prime number
0
the next prime number
0
the next prime number
0
the next prime number
0
the next prime number
0
.
.
the last prime number (which can be N if N is a prime one)
The theorem used for this program is:
You choose a number
You calculate its square root
1, here is not a considered prime number because it divides all prime
numbers.
You write all the numbers from 2 to the number you choose
You remove every multiples of prime numbers (the prime numbers used here are those under the square root) every where in the written list (here an array where we write 0 because I don't know how to use structs (list?) for now).
The numbers which stay are all prime numbers under the one you chose (rest? sorry for my bad English)
Thanks.
the following proposed code:
cleanly compiles
performs the desired functionality
is NOT efficient
shows proper indentation
shows meaningful variable names
properly passes the allocated memory to `free_ before exiting
properly checks for successful execution of scanf()
and now, the proposed code:
/*librairies*/
#include <stdio.h>
#include <stdlib.h>
/*main function*/
int main( void )
{
size_t targetNum;
size_t i; // index
size_t j; // index
size_t *primeArray = NULL; /*pointer which will become an array (see in another after comment)*/
printf("Enter Your target number : ");
if( scanf("%lu", &targetNum) != 1 )
{
fprintf( stderr, "scanf failed to read target number\n" );
exit( EXIT_FAILURE );
}
if ( targetNum > 1 )
{
primeArray = malloc( targetNum * sizeof( size_t ) );
if ( !primeArray )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// initialize array of prime numbers
for ( i = 0; i < targetNum; i++ )
{
primeArray[i] = 1;
}
primeArray[0] = 0;
primeArray[1] = 0;
// find primes and zero multiples
for( i = 0; i < targetNum; i++ )
{
// skip any multiples of primes (which have already been zero'd
if( !primeArray[i] )
{
continue;
}
// zero multiples
for( j = i+i; j < targetNum; j+=i )
{
primeArray[j] = 0;
}
}
// print primes
for ( i = 0; i < targetNum; i++ )
{
if( primeArray[i] )
{
printf( "%lu\n", i );
}
}
free( primeArray );
}
else
{
printf("Your number is not valid\n");
}
return 0;
}
given the following input:
4
the output is:
Enter Your target number : 4
2
3

How to check whether a no is factorial or not?

I have a problem, then given some input number n, we have to check whether the no is factorial of some other no or not.
INPUT 24, OUTPUT true
INPUT 25, OUTPUT false
I have written the following program for it:-
int factorial(int num1)
{
if(num1 > 1)
{
return num1* factorial(num1-1) ;
}
else
{
return 1 ;
}
}
int is_factorial(int num2)
{
int fact = 0 ;
int i = 0 ;
while(fact < num2)
{
fact = factorial(i) ;
i++ ;
}
if(fact == num2)
{
return 0 ;
}
else
{
return -1;
}
}
Both these functions, seem to work correctly.
When we supply them for large inputs repeatedly, then the is_factorial will be repeatedly calling factorial which will be really a waste of time.
I have also tried maintaining a table for factorials
So, my question, is there some more efficient way to check whether a number is factorial or not?
It is wasteful calculating factorials continuously like that since you're duplicating the work done in x! when you do (x+1)!, (x+2)! and so on.
One approach is to maintain a list of factorials within a given range (such as all 64-bit unsigned factorials) and just compare it with that. Given how fast factorials increase in value, that list won't be very big. In fact, here's a C meta-program that actually generates the function for you:
#include <stdio.h>
int main (void) {
unsigned long long last = 1ULL, current = 2ULL, mult = 2ULL;
size_t szOut;
puts ("int isFactorial (unsigned long long num) {");
puts (" static const unsigned long long arr[] = {");
szOut = printf (" %lluULL,", last);
while (current / mult == last) {
if (szOut > 50)
szOut = printf ("\n ") - 1;
szOut += printf (" %lluULL,", current);
last = current;
current *= ++mult;
}
puts ("\n };");
puts (" static const size_t len = sizeof (arr) / sizeof (*arr);");
puts (" for (size_t idx = 0; idx < len; idx++)");
puts (" if (arr[idx] == num)");
puts (" return 1;");
puts (" return 0;");
puts ("}");
return 0;
}
When you run that, you get the function:
int isFactorial (unsigned long long num) {
static const unsigned long long arr[] = {
1ULL, 2ULL, 6ULL, 24ULL, 120ULL, 720ULL, 5040ULL,
40320ULL, 362880ULL, 3628800ULL, 39916800ULL,
479001600ULL, 6227020800ULL, 87178291200ULL,
1307674368000ULL, 20922789888000ULL, 355687428096000ULL,
6402373705728000ULL, 121645100408832000ULL,
2432902008176640000ULL,
};
static const size_t len = sizeof (arr) / sizeof (*arr);
for (size_t idx = 0; idx < len; idx++)
if (arr[idx] == num)
return 1;
return 0;
}
which is quite short and efficient, even for the 64-bit factorials.
If you're after a purely programmatic method (with no lookup tables), you can use the property that a factorial number is:
1 x 2 x 3 x 4 x ... x (n-1) x n
for some value of n.
Hence you can simply start dividing your test number by 2, then 3 then 4 and so on. One of two things will happen.
First, you may get a non-integral result in which case it wasn't a factorial.
Second, you may end up with 1 from the division, in which case it was a factorial.
Assuming your divisions are integral, the following code would be a good starting point:
int isFactorial (unsigned long long num) {
unsigned long long currDiv = 2ULL;
while (num != 1ULL) {
if ((num % currDiv) != 0)
return 0;
num /= currDiv;
currDiv++;
}
return 1;
}
However, for efficiency, the best option is probably the first one. Move the cost of calculation to the build phase rather than at runtime. This is a standard trick in cases where the cost of calculation is significant compared to a table lookup.
You could even make it even mode efficient by using a binary search of the lookup table but that's possibly not necessary given there are only twenty elements in it.
If the number is a factorial, then its factors are 1..n for some n.
Assuming n is an integer variable, we can do the following :
int findFactNum(int test){
for(int i=1, int sum=1; sum <= test; i++){
sum *= i; //Increment factorial number
if(sum == test)
return i; //Factorial of i
}
return 0; // factorial not found
}
now pass the number 24 to this function block and it should work. This function returns the number whose factorial you just passed.
You can speed up at least half of the cases by making a simple check if the number is odd or even (use %2). No odd number (barring 1) can be the factorial of any other number
#include<stdio.h>
main()
{
float i,a;
scanf("%f",&a);
for(i=2;a>1;i++)
a/=i;
if(a==1)
printf("it is a factorial");
else
printf("not a factorial");
}
You can create an array which contains factorial list:
like in the code below I created an array containing factorials up to 20.
now you just have to input the number and check whether it is there in the array or not..
#include <stdio.h>
int main()
{
int b[19];
int i, j = 0;
int k, l;
/*writing factorials*/
for (i = 0; i <= 19; i++) {
k = i + 1;
b[i] = factorial(k);
}
printf("enter a number\n");
scanf("%d", &l);
for (j = 0; j <= 19; j++) {
if (l == b[j]) {
printf("given number is a factorial of %d\n", j + 1);
}
if (j == 19 && l != b[j]) {
printf("given number is not a factorial number\n");
}
}
}
int factorial(int a)
{
int i;
int facto = 1;
for (i = 1; i <= a; i++) {
facto = facto * i;
}
return facto;
}
public long generateFactorial(int num){
if(num==0 || num==1){
return 1;
} else{
return num*generateFactorial(num-1);
}
}
public int getOriginalNum(long num){
List<Integer> factors=new LinkedList<>(); //This is list of all factors of num
List<Integer> factors2=new LinkedList<>(); //List of all Factorial factors for eg: (1,2,3,4,5) for 120 (=5!)
int origin=1; //number representing the root of Factorial value ( for eg origin=5 if num=120)
for(int i=1;i<=num;i++){
if(num%i==0){
factors.add(i); //it will add all factors of num including 1 and num
}
}
/*
* amoong "factors" we need to find "Factorial factors for eg: (1,2,3,4,5) for 120"
* for that create new list factors2
* */
for (int i=1;i<factors.size();i++) {
if((factors.get(i))-(factors.get(i-1))==1){
/*
* 120 = 5! =5*4*3*2*1*1 (1!=1 and 0!=1 ..hence 2 times 1)
* 720 = 6! =6*5*4*3*2*1*1
* 5040 = 7! = 7*6*5*4*3*2*1*1
* 3628800 = 10! =10*9*8*7*6*5*4*3*2*1*1
* ... and so on
*
* in all cases any 2 succeding factors inf list having diff=1
* for eg: for 5 : (5-4=1)(4-3=1)(3-2=1)(2-1=1)(1-0=1) Hence difference=1 in each case
* */
factors2.add(i); //in such case add factors from 1st list " factors " to " factors2"
} else break;
//else if(this diff>1) it is not factorial number hence break
//Now last element in the list is largest num and ROOT of Factorial
}
for(Integer integer:factors2){
System.out.print(" "+integer);
}
System.out.println();
if(generateFactorial(factors2.get(factors2.size()-1))==num){ //last element is at "factors2.size()-1"
origin=factors2.get(factors2.size()-1);
}
return origin;
/*
* Above logic works only for 5! but not other numbers ??
* */
}

Resources