c function not returning result - c

I've very recently started to learn C, so I realize my question is very basic, but any help would be very much appreciated.
I'm trying to get the function fact to return the res value to main, but when I print out the result in main I just get 0. By inserting some print statements I can see that res is calculating correctly in the fact routine but the result is not returning correctly to main.
I'm sure I'm missing something very basic here.
Thanks
#include <stdio.h>
unsigned long fact (int n){
unsigned long res = 1;
while ( n >= 0 )
{
res *= n;
n--;
}
return res;
}
int main (void){
int n;
unsigned long res;
printf("Insert number:\n");
scanf("%d", &n );
res = fact (n);
printf("The factorial number is %lu", res);
return 0;
}

Your loop condition is n >= 0, which means that res will be multipled by 0 before the function returns. Thus the result will always be 0.

You loop condition is wrong. The last run of while (n>=0) will have n=0. Multiplying res by this will reset it to 0.
You can fix this by changing your loop to while (n > 1)
For future reference, you could investigate problems like this using a debugger (e.g. GDB or visual studio express). Or by adding printf statements to your code to trace the flow and see how the value of res changed through the program.

Related

why does it show segmentation fault when I tried to use recursion here?

I tried to write a code to calculate how many 1 are there in a number's binary form. This is my code:
#include <stdio.h>
#include <math.h>
static int num = 0;
void binary(int target){
int n = 0;
int a = 1;
if(target != 0){
while(target >= a ){
n++;
a = pow(2, n);
}
a = pow(2, n-1);
num++;
binary(target - a);
}
}
int main() {
int target = 0;
scanf("%d", &target);
binary(target);
printf("%d",num);
return 0;
}
However, this shows segmentation fault when I run it. I don't know where has the code tried to access memories that are not allowed. I figured it might have something to do with the recursion in the binary function. Can anyone tell me what have caused the segmentation fault here? Thank you so much. I really can't understand segfaults :(
As mentioned in the comments, pow is not a good candiate here due to its signature:
double pow(double x, double y);
so any place that you are using pow, you are implicitly using floating point numbers. I was able to cause a segfault with the input 1<<31 which is the value -2147483648. This will cause your loop to terminate with n=0, a=1. You then set a = pow(2, -1), but since a is an integer, this gets floored down to just 0. You then recurse with binary(target - 0) which might as well just be binary(target) again, hence you have an infinite call with no termination.
I'll also leave as a note that recursion for this type of problem is probably not the right tool, unless your goal is to learn about recursion. There is a much more concise and reliable method via a loop and the & operator. I would also suggest using unsigned values to avoid issues like this with negative terms.

Why does this simple C program hang up?

int getCycleLen(int n){//counts the number of iterations before n=1
int cycle_len=0;
while(n!=1){
if(n%2==0) n/=2; else n=3*n+1;
cycle_len++;
}
return cycle_len;
}
int main(){
int i,j,n;
int max_len=0,len;
i = 1; j = 1000000;//j = a million
for(n=i;n<=j;n++){
printf("%d ",n);
len = getCycleLen(n);
if(len > max_len)
max_len=len;
}
printf("%d %d %d\n",i,j,max_len);
}
I am using Ubuntu 16.04 and compiling using gcc 5.4. For some reason the program hangs when n of the for loop is 113299. Any suggestions as to why this happens?
This is an integer overflow. Use a long for the parameter to getCycleLen instead.
You can see this for yourself if you print every value of n as you iterate in getCycleLen. When the number gets too big to fit in an int, it will overflow and become a negative number. The negative numbers will then not converge on 1.
In C, integers have a specific limit. This limit depends on the architecture of your system. But basically your value has overflowed the the max possible value stored at an integer.

I cant write this factorial codes

I have some problem with that. I am trying to learn C programming. Please help me
#include<stdio.h>
int main()
{
int a, factorial;
printf("Please enter a value :" );
scanf("%d", &a);
for (int i = 1; i<=a; i++)
{
a = (a - 1)*a;
}
printf("%d", factorial);
return 0;
}
Well in your code line a = (a - 1)*a; you actually changed your input for getting the factorial. It also will blow your loop. See your for loop will continue as long as your i is less than a, lets say you choose a=3 after first iteration the a itself will become 6, so the for loop will continue until it reach the integer limit and you will get overflow error.
What you should do?
First of all you should use a second variable to store the factorial result, you introduced it as factorial, the way that #danielku97 said is a good way to write a factorial since if you present 0 as input it will also give the correct result of 1. so a good code is:
factorial = 1;
for (int i = 1; i<=a; i++)
{
factorial *= i;
}
But lets say you insist of subtraction, the way you just tried to use, then you need to change the code like:
scanf("%d", &a);
if (a==1 || a==0){
printf("1");
return 0;
}
factorial = a;
for (int i = 1; i<a; i++)
{
factorial *= (a - i)*factorial;
}
You can see that the code just got unnecessarily longer. An if included to correct the results for 1 and 0. Also you need to make sure that i never become like i =a since in that case a-i will be equal to zero and will make the factorial result equal to zero.
I hope the explanations can help you on learning C and Algorithm faster.
Your for loop is using your variable 'a' instead of the factorial variable and i, try something like this
factorial = 1;
for (int i = 1; i<=a; i++)
{
factorial *= i;
}
You must initialize your factorial to 1, and then the for loop will keep multiplying it by 'i' until 'i' is greater than 'a'.
You are modifying the input a rather than factorial and also wrong (undefined behaviour) because you are using factorial uninitialized. You simply need to use the factorial variable you declared.
int factorial = 1;
...
for (int i = 1; i<=a; i++) {
factorial = i*factorial;
}
EDIT:
Also, be aware that C's int can only hold limited values. So, beyond a certain number (roughly after 13! if sizeof(int) is 4 bytes), you'll cause integer overflow.
You may want to look at GNU bugnum library for handling large factorial values.

Runtime error in my code

I was trying to implement this problem from SPOJ: http://www.spoj.com/problems/COINS/ using memoization but I keep getting Runtime error and cant figure out why. Here is my code:
#include<stdio.h>
long long int max(long long int a,long long int b)
{
if(a >= b)
return a;
else
return b;
}
long long int dp[100000];
long long solve(long long int n)
{
long long ans;
if(n<=50000)
return dp[n];
else
ans=(n,solve(n/2)+solve(n/3)+solve(n/4));
return ans;
}
int main()
{
long long int n;
int t;
for(int i = 0;i <=50000;i++)
{
dp[i] = max(i,dp[i/2] + dp[i/3] + dp[i/4]);
}
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
return 0;
}
Here are a few problems:
In solve, you have ans = (n,solve(n/2)...); The leading n has no effect. Did you intend this to be an argument list to max? If so, you need to add max. Otherwise it's just a comma expression and you might as well remove the leading n.
In main, your initialization of dp has a problem. Consider the first pass through the loop, when i is 0. In this case, i/2 etc. will also be zero, hence those dp values will be undefined. Try setting dp[0] explicitly, outside of the loop, and then start your loop at index 1 instead.
When printing the solution in main, you probably want to add newling \n to the end of your printf format string.
As noted by others, when calling solve from main, you are passing n rather than t.
The problem is most likely due to this:
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
You are reading t but passing n which is uninitialized. You probably want to pass t to solve():
while((scanf("%d",&t))>0)
printf("%lld",solve(t));
Reason you get Runtime Error
while((scanf("%d",&t))>0)
printf("%lld",solve(n));
Here, You get input in variable t but pass variable n to solve function. Use variable t or n for both case. It will solve your problem.

Scanf seems to be working incorrectly, or I am doing something wrong

So I am trying to do a simple program finding the greatest common denominator of any two values, but it keeps giving me this error message,
"xxx.exe has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available."
and crashes my program. I am thoroughly confused, if you have any input, please help!
This is my code:
#include <stdio.h>
int main (void) {
int first, second;
//Scans in variables
printf("What numbers would you like to find the GCD of?\n");
scanf("%d%d",&first,&second);
int gcd = (first%second);
//Loop
while (gcd !=0)
{
first = second;
second = (first%second);
gcd = (first%second);
}
//Prints output
printf("Your GCD is: %d", second);
return 0;
}
As problems with scanf are the only times I have ever seen this error message before, I have tried changing the
scanf("%d%d", &first, &second);
to a variety of things, but it still doesn't work.
You are getting divide by zero error
After 2nd statement below second variable will be zero as first and second are holding same number
so 3rd statement gives divide by zero
first = second;
second = (first%second);
gcd = (first%second);
Here is a way to calculate GCD
int
gcd ( int a, int b )
{
int c;
while ( a != 0 ) {
c = a; a = b%a; b = c;
}
return b;
}
This has nothing to do with the scanf function. I think the following code caused the issue:
...
first = second // now first equals second
second = (first % second) // now second is 0
gcd = (first % second) // mod 0, Arithmetic Exception thrown out here
...
The issue is you mod 0 which is just like divide a number by 0. If this is not obvious to you, you can use a debugger to verify this.
Are you sure this is a scanf issue. If second is 0, your program will crash.

Resources