Wrong output for prime numbers [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
#include <stdio.h>
int main()
{
int i, n, c, p;
printf("enter\n");
scanf("%d", n);
c = find(n);
if (c == 1)
{
printf("no. is not prime");
}
else
{
printf("no. is prime");
}
}
find(int n)
{
int i = 2, p;
while (i < n)
{
p = n % i;
printf("value of p%d", p);
if (p == 0)
{
return 1;
}
i = i + 1;
}
return 2;
}
....................................
Above program giving me 'not a prime number' output for all inputs...also the value of p is always zero and this shouldn't be the case...
Please help...badly stuck...

Your scanf() call must take the address of n. Furthermore you primality test fails for numbers smaller than 2. It is also better to return non-zero for true, zero otherwise, so that the value can directly be tested with if. And you should find a better name than find.
Try something like this:
#define TRUE 1
#define FALSE 0
int is_prime (int n)
{
int i;
if (n < 2)
return FALSE;
for (i = 2; i < n; i++) {
if (n % i == 0) {
return FALSE;
}
}
return TRUE;
}
int main()
{
int n;
printf ("enter number: ");
scanf ("%d", &n);
if (is_prime (n)) {
printf ("number is prime.\n");
}
else {
printf("number is not prime.\n");
}
return 0;
}
Various improvements are possible but I wanted to stay as close to your code as possible.

This looks like a student exercise so let me start by suggesting that the debugger is your friend. :)
Having said that, you may want to review the Sieve of Eratosthenes and leverage Wikipedia for a source of some good test content.
As already suggested, there are loads of potential improvements... I'd modify your "find" function to be more clear as follows:
bool IsPrime(unsigned int n)
{
unsigned int nCounter = 2;
while (n % nCounter++);
return (nCounter > n);
}
Prime's can't be negative and since you're asking a "TRUE/FALSE" question, the name and return type should enforce that contract.

Several issues:
scanf("%d", n); should be scanf("%d", &n); - you need to pass the address of n so scanf can update it (note that you risk a runtime error,
since the value of n most likely isn't a valid address value);
Implicit typing of functions such as find(int n) {...} is no longer supported as of the C99 standard, and it was never good practice to begin with. You should (and for C99 and later, must) provide a type specifier along with the function name in both function declarations and function definitions - int find( int n ) {...};
Similar to 2, a function declaration must be visible before a function is called; the simplest way to accomplish this is to move the function definition above the definition for main. If you don't want to do that, then you need to add the declaration int find(int n); somewhere before find is called.
Note that you can speed up the primality test in a couple of ways. First, you can skip testing against even factors; if a number is divisible by a multiple of 2, then it's divisible by 2, and you would have already checked for that. Secondly, you don't need to test all factors up to n - 1; you only need to test factors up to the square root of n. You can put that all together like so:
if ( n < 2 )
return 0; // zero indicates false
if ( n == 2 )
return 1; // non-zero indicates true
int result = n % 2;
for ( int i = 3; result && i * i <= n; i += 2 ) // loops as long as result
result = n % i; // is non-zero, only tests
// against odd numbers up to
return result; // sqrt(n)

Related

pass by reference recursive function without initialising the reference

This is a recursive function to find the amount of 2 appearing in a number.
Example Input:
221122
Example Output:
countTwo(): 4
#include <stdio.h>
void countTwo2(int num, int *result);
int main()
{
int number, result;
printf("Enter the number: \n");
scanf("%d", &number);
countTwo2(number, &result);
printf("countTwo2(): %d\n", result);
return 0;
}
void countTwo2(int num, int *result)
{
if(num > 0) {
if((num % 10)/2 == 1) {
*result += 1;
}
countTwo2(num/10, result);
}
}
I can't increment result since it has not been initialised but I also can't initialise result in the recursive function as this will reset the result.
Edit: This is a question given, with all the template written as above except for the code within countTwo. We are supposed to write the code in countTwo such that main() will be able to run.
Edit2: Thanks for the help! This problem has been solved by using static int. I understand that this is not very efficient. I will also ask my teacher pertaining to this question. Once again, Thanks!
The way to keep all the oddities of this code:
it has to be recursive
you cannot change main, so the initial result value will be undefined
is to, as you stated you cannot do, actually reset result inside countTwo2. However, you need to it in the right place, before you start incrementing.
The way to do that is to reorder your function and add the part that resets the value at the right place:
void countTwo2(int num, int* result)
{
if (num > 0)
{
countTwo2(num / 10, result);
if ((num % 10) / 2 == 1)
{
*result += 1;
}
}
else
*result = 0;
}
Notice that I moved the recursive call up above the if-then block that increments the result, and that when num is 0, we reset. This will call recursively down digits of the input until we're at the end, then reset the result, then return back up one digit at a time and optionally increment the value.
This requires no other changes to your code.
As many have stated, in comments and answers, this is obviously not a good implementation or design but if you have a confined context to work in, this is probably as good as it gets.
I can't see any good reason for declaring this as a void function with the result passed back via pointer parameter.
The following would be a lot cleaner, surely?
int countTwo(int num) {
return (num == 0) ? 0 : (num % 10 == 2) + countTwo(num / 10);
}
For reference, the proper way to write such a function is to not use recursion. It isn't obvious that the compiler will be able to unroll the recursion in this case, as the recursive call would be in the middle of the function, and also conditional.
Thus the only thing gained from recursion is slow execution and higher stack peak use. Why would we want slow execution when we can have fast execution? You should ask your teacher this question, so they can tell you why they are teaching it. I would be most curious to hear their rationale.
For a professional, non-academic programmer, the proper way to write the function would be to use a loop:
int count_n (int input, int n)
{
int result = 0;
for(; input>0; input/=10)
{
if(input%10 == n)
{
result++;
}
}
return result;
}
(This version doesn't work with negative numbers.)
As I mentioned before you may use static variables.
You do not need two arguments.
Here is a solution: #Lasse Vågsæther Karlsen
#include <stdio.h>
int countTwo2(long int num)
{
static int m=0; //static variable is initialized only once.
if (num==0)
return m;
else if (num % 10 ==2)
m=m+1;
num=num /10;
countTwo2(num);
}
int main()
{
int result; long int number;
printf("Enter the number: \n");
scanf("%ld", &number);
result=countTwo2(number);
printf("countTwo2(): %d\n", result);
return 0;
}

C Function: Count the occurrences of a digit in an integer [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I'm receiving Output: 1. I should count the number of times a digit appear in an integer, for example, for number 1222345 and n = 2 Should appear 3 times.
int countOccurrences(int n, int num)
{
int i,k;
i=0;
while(num!=0)
{
k=num%10;
num=num/10;
if(k==n)
{
i++;
}
}
}
// Main
void main()
{
int num= 1222345;
int n = 2;
printf("Occurance of a number: %d", countOccurrences(n,num));
}
You have undefined behavior in the code. The function is supposed to return an int and it didn't.
Solution is to add return i in the end of other function. This will give you correct result. In the countOccurrences() function
...
if(k==n)
{
i++;
}
}
return i;
}
I was skipping the discussion of error check and all that. As chux mentioned for n<=0 case you might want to add a different way of handling it but you didn't add it. Atleast consider those case and put an error message on whatever input you need.
Some corner cases are
n=0,m=0.
Negative value of n or m.
Put a return on your countOccurrences function please
int countOccurrences (int n, int num) {
int i, k;
i = 0;
while (num! = 0)
{
k = num% 10;
num = num / 10;
if (k == n)
{
i ++;
}
}
return i; }
As other have pointed out, there are important issues with your code.
Here is a recursive solution that you may find interesting:
int countOccurrences(int n, int num)
{
int count = ((num % 10) == n);
return (num < 10) ? count : count + countOccurrences(n, num / 10);
}
Few general remarks about your code:
When using printf(), you should #include <stdio.h>.
main() should return int.
Place spaces around operators and format your code consistently. This k = num % 10; is more readable than k=num%10;. (There's more to code formatting than a matter of taste; without spaces you create areas full of characters which are more difficult to parse for our visual system.)

Recursively finding prime factors

I am starting to teach myself C and am trying to build a group of useful functions and programs for future reference. If relevant, this is C99.
Here is my most recent iteration of the program. At the output, I want to get the prime factorization of a number n. As is, however, I get a list of all factors, and no factors are repeated. I included some print statements to try and debug, and have found that the error is with the recursion, but can't figure out how to interpret it further. I previously tried making the recursive function of type int, but had difficulties getting it to work with the array p.
n is the number that I am trying to factor
p is an array for storing the found primes
j is an index for p
c is the number that I am testing as a divisor to n
I am aware that there are probably more efficient ways to declare p to save memory, but since this is mainly for reference, memory is not a huge concern.
I found these questions but don't think that they answer my question
finding greatest prime factor using recursion in c :This question is about crashing code. Mine compiles, runs, and produces reasonably sensible output, I'm just wondering why the output isn't what I expect.
is there ever a time you would not use recursion? [closed] :This indicates that recursion is not a good choice for prime factorization- I don't know, but suspect that this would also apply to C. Since this is for reference, I don't think it is a huge issue. If you disagree, please explain why.
My main questions are these:
Why does the output show all factors of n?
Why does it not repeat the prime factors?
What do I have to do to fix it?
#include <stdio.h>
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
void factors(int n, int p[], int j) {
/// if n is divisible by c, store c, and continue with n/c
int c;
for (c=2; c < n; c++) {
if (c > n) break;
if (n%c == 0) {
p[j] = c;
printf("%d has been added to p \t", c);
printf("n has been reduced to %d \t", n/c);
printf("j is %d \n", j);
j++;
if (n == c) break;
factors(n/c, p, j);
}
}
}
int main() {
/// set up number to factor, and array to hold factors
int n = 24;
int p[n/2];
int i=0;
for (i=0; i<NELEMS(p); i++) {
p[i]=0;
}
int j = 0;
factors(n, p, j);
printf("the prime factors of %d are:\n",n);
for (i=0; i<NELEMS(p); i++) {
printf("%d \n", p[i]);
}
}
You have already been told in comments that this algorythm is poor, which is an evidence here. And you really should learn to use a debugger: running this through a debugger immediately shows where the problems are.
That being said, your main problem here is what to do when the recursive functions return?. You failed to ask yourself this question which is a must in recursion, and simply continue in sequence, which is plain wrong because you will reuse a number that has already been processed in the recursive calls. So you must add a return line immediately after recursively calling factors.
Once this is done, there is another minor problem (that a debugger would make evident), you only search factors strictly lesser that n. So you miss the last prime factor...
With those 2 immediate fixes, your code becomes:
void factors(int n, int p[], int j) {
/// if n is divisible by c, store c, and continue with n/c
int c;
for (c=2; c <= n; c++) {
if (c > n) break;
if (n%c == 0) {
p[j] = c;
printf("%d has been added to p \t", c);
printf("n has been reduced to %d \t", n/c);
printf("j is %d \n", j);
j++;
if (n == c) break;
factors(n/c, p, j);
return;
}
}
}
But IMHO p[j] = c; should become *p = c; and factors(n/c, p, j); should become factors(n/c, p+1, j);. Said differently you pass directly a pointer to the next slot.
Edit It occurs to me that the smallest factor of n is guaranteed to be prime, so I have edited the answer accordingly.
Why does the output show all factors of n?
Because you test if c is a factor of n and add it to the array p whether c is prime or not. Then you carry on testing numbers above c, even multiples of c.
Why does it not repeat the prime factors?
Because when you find a number c that is a factor, you don't necessarily inspect it to find out if it is a compound number itself.
After adding c to p, you need to recursively call factor on (n / c) and then stop.
Here is roughly what you need (but not tested or even compiled)
int factorise(int n, int p[], int j)
{
int factorsFound = 0;
for (c = 2 ; c * c <= n && factorsFound == 0 ; ++ c)
{
if (n % c == 0)
{
p[j] = c;
factorsFound = factorise(n / c, p, j + 1) + 1;
}
}
if (factorsFound == 0) // n is prime
{
p[j] = n;
factorsFound = 1;
}
return factorsFound;
}
Also in a real solution, you probably want to pass the size of p so that you can detect if you run out of space.
Just for fun, since nobody else has posted it yet, here is a non recursive solution. It's actually the same as above but the recursion has been transformed into a loop.
int factorise(int number, int p[])
{
int j = 0;
for (int c = 2, int n = number ; n > 1 ; )
{
if (n % c = 0)
{
p[j++] = c;
n = n / c;
}
else
{
c++;
}
}
return j;
}
I disagree with some of Lundin's comments about recursion. Recursion is a natural way of breaking a problem down into easier subtasks but in C it is undeniably less efficient, especially in terms of stack space and in this particular case, the non recursive version is simpler.
From This answer:
why does recursion cause stackoverflow so much more than loops do
Because each recursive call uses some space on the stack. If your recursion is too deep, then it will result in StackOverflow, depending upon the maximum allowed depth in the stack.
When using recursion, you should be very careful and make sure that you provide a base case. A base case in recursion is the condition based on which the recursion ends, and the stack starts to unwind. This is the major reason of recursion causing StackOverflow error. If it doesn't find any base case, it will go into an infinite recursion, which will certainly result in error, as Stack is finite only.
-
It appears that your for is in the way, c will increment, and wont check that same value again.
For instance, if the input is 8, we want (2,2,2) and not (2,4).
I would recommend replacing your if (c%n ==0) by a while, don't forget to replace the value of n in that while, you don't want to loop in that.
This appears to be a good answer :
int primes(int nbr, int cur)
{
if (cur > nbr)
return (0);
else
{
if (nbr % cur == 0 && isprime(cur) == 1)
{
printf("%d\n", cur);
return (primes(nbr / cur, 2));
}
return (primes(nbr, cur + 1));
}
}
Call that function with cur = 2 in your main

Function return value in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am an absolute newbie to the C language (I started today to learn it). As a test I wrote this program to output all prime numbers between two ranges. I then optimized and shortened the checkIfPrime function with some google help and took all return statements out of the function, for it obviously doesn't need to have a return value to understand I want to have the flag variable back. How does the function returns the flag variable even without any returns in it?
#include <stdio.h>
int checkIfPrime(int n);
int main(int argc, char *argv[]) {
int n1, n2;
scanf("%d %d", &n1, &n2);
for (int i = n1; i < n2; i++) {
if (checkIfPrime(i)) {
printf("%s", "Is prime: ");
printf("%d\n", i);
}
}
return 0;
}
int checkIfPrime(int n) {
int flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
}
Unlike some languages such as Groovy where the last expression evaluated by a function is the return value of the function, in C you need to explicitly state the return value with a return statement.
int checkIfPrime(int n)
{
int flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
return flag;
}
If you fail to explicitly return a value from a function that expects one, your code invokes undefined behavior.
As an example of undefined behavior, your original code give the "correct" answer for me, but if I change the function to this:
int checkIfPrime(int n) {
int flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
// this loop should have no effect
for (int i = 2; i <= (n / 2); i++) {
}
}
In a properly behaving program, the extra loop added should have no effect. But without a return, I get back this if I input 2 and 10:
Is prime: 2
Is prime: 3
Is prime: 4
Is prime: 5
Is prime: 6
Is prime: 7
Is prime: 8
Is prime: 9
If you had put the return statement in place at the end of the function, things like this wouldn't happen.
Why the above code behaves the way it does is an implementation detail of the compiler in use. A different compiler may have different output, or the same compiler with different optimization settings could have different output.
Your current function int checkIfPrime(int n) is by its definition saying it will return an int, so you must then return an int value.
If you really didn't want to return a value using the return statement, you could pass the value back as a pointer to a variable to store the flag in:
void checkIfPrime(int n, int *flag) {
*flag = 1;
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
*flag = 0;
break;
}
}
}
Its far easier to read and understand using a return of the value though, and main would then have to change to allocate a new variable and would have to call the function and then check the variable - much nicer just using the return value.
There are only two ways to give a value back from a function: explicitly return a value, or mutate a variable external to the function.
Except when writing OO code (and in that case you're mutating object fields), or a void function, your functions should always explicitly return a value.
Since you gave your function a return type, I'm surprised the compiler didn't raise an error.
You shouldn't try to avoid using return statements; avoid using them in ways that lead to confusing code.
How does the function returns the flag variable even without any returns in it?
It doesn't; or, it doesn't do so in a predictable or reliable manner.
The intent is that if you define a function T f() { ... } and T is not void, then you will have at least one return statement returning a value of type T.
For whatever reason, the language definition does not mandate a return statement in a non-void function1 (the compiler may complain, but it's not required to), but if the caller attempts to use the return value of the function and you don't explicitly return a value, then the behavior is undefined, meaning any result you get (whether expected or not) is considered "correct".
Interestingly, it does mandate that a return statement in a void function not return a value.

Compiler wants ";" - I don't know why (in C) [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Working on a project Euler problem (#10), I've an interesting compile error. My compiler tells me I need a semicolon. The exact error is 49: ';' expected.
Now I know this is not unusual with C code, but the problem is I've triple checked all semicolons and parentheses and brackets, and none are missing. Not even in loops. Chances are I'm just missing it.
HOWEVER
The compiler tells me 49: ';' expected - but the code on line 49 is just one bracket ({).
Would anyone have any insight into what might be wrong here?
Code is as follows:
// this is a program to find the sum of all primes below 2 million
// uses the Seive of Eratosthenes
#include <stdio.h>
int main() {
long int sum = 0;
long int s = 2000000; // size of array
long int i; // 'for' loops
long int n; // number to test
long int a; // prime checker
long int multiples;
long int* array; // define pointer for calloc int array
// calloc the array
array = (int*)calloc(s, sizeof(int)); // allocates 2,000,000 spots (s) of
// size "int" to array "array"
// set all array values equal to 1
for (i = 0; i < 2000000; i++) {
array[i] = 1;
}
/*
VALUES IN ARRAY
The values of the array indicates whether number-
(0) IS PRIME
(1) UNTESTED
(2) IS COMPOSITE
*/
// implement prime finder
for (n = 0; n < 2000000; n++) {
if (array[n] == 0) // IF n IS PRIME
{
multiples = n;
multiples += n;
while (multiples < 2000000) {
array[multiples] = 2;
multiples += n;
}
} else
(array[n] == 2) // IF n IS COMPOSITE (is a multiple)
{ // THIS IS LINE 49
continue;
}
else(array[n] == 1) // UNTESTED
{
for (a = 2; a < n; a++) // double checks for composites
{
// tests factors
if (n % a == 0) {
printf("ERROR");
goto end;
}
}
array[n] = 0;
multiples = n;
multiples += n;
while (multiples < 2000000) {
array[multiples] = 2;
multiples += n;
}
}
}
// read array and sum primes
for (n = 0; n < 2000000; n++) {
if (array[n] == 0) // IF n IS PRIME
{
sum += n;
} else
(array[n] == 2) // IF n IS COMPOSITE
{
continue;
}
else(array[n] == 1) // IF n MAY/MAY NOT BE PRIME
{
printf("ERROR");
goto end;
}
}
printf("The sum of all primes < 2,000,000 is... %ld!\n", sum);
end:
getchar();
return 0;
}
Change the else to else if and you are fine.
And do that with all the else.
else( array[n] == 2) // IF n IS COMPOSITE (is a multiple)
{ //THIS IS LINE 49
else doesn't take a condition. The else should be else if.
The compiler's syntax recovery tries to suggest the simplest change that would result in a syntactically valid program. Often the suggested change doesn't make much sense. In this case, adding a ; after the else would turn the following ( array[n] == 2) into the beginning of an expression statement (which would have to be followed by another semicolon).
If your code produces a syntax error message, the best approach is often to ignore the suggestion it makes and just look at the line it refers to and the line(s) preceding it, and figure out what's wrong with the syntax at that point. Then fix the error and recompile.
You're really missing is some ifs to go with your elses:
if( array[n] == 0) // IF n IS PRIME
{
sum += n;
}
else if( array[n] == 2) // IF n IS COMPOSITE
{
continue;
}
else if( array[n] == 1) // IF n MAY/MAY NOT BE PRIME
{
printf("ERROR");
goto end;
}
It's pretty easy to confuse a compiler like this, and when you do, some of its error messages can get hard to understand.

Resources