Unable to get a factorial function to work in C - c

I cannot get the following code to work.
#include <stdio.h>
// I am not sure whethere I should void here or not.
int main() {
// when the first bug is solved, I put here arg[0]. It should be
// similar command line parameter as args[0] in Java.
int a=3;
int b;
b = factorial(a);
// bug seems to be here, since the %1i seems to work only in fprintf
printf("%1i", b);
return 0;
}
int factorial(int x) {
int i;
for(i=1; i<x; i++)
x *= i;
return x;
}
How can you get the code to work?

You're modifying your loop terminating variable (x) inside the loop. Currently your code blows up after a few iterations, when x overflows the range of a 32 bit integer and then becomes negative and very large, hence terminating the loop.
It should be:
int factorial(int n) {
int i, x = 1;
for (i = 2; i <= n; ++i) {
x *= i;
}
return x;
}
Better yet, you should use long instead of int for the variable x and the return value, because n! gets very large very quickly.

AInitak gave the right answer, but I want to add that one way you can find the bug in your code is to print out the values of i and x in the factorial loop.
int factorial(int x) {
int i;
for(i=1; i<x; i++)
{
x *= i;
printf("%d, %d\n", i, x);
}
return x;
}
This gives you the output
1, 3
2, 6
3, 18
4, 72
5, 360
6, 2160
7, 15120
8, 120960
9, 1088640
10, 10886400
11, 119750400
12, 1437004800
13, 1501193216
14, -458131456
-458131456
This makes it easier to see what's going wrong. The loop doesn't stop where you expect it to for the reasons AInitak explained.

It's bad style in C to leave out void when defining or declaring a function. So put it in
int main(void)
While it doesn't change anything about the number of parameters the function has (the function has zero parameters without that void either), it will declare the function as one that accepts only zero arguments, while it won't tell anything about the amount and types of accepted arguments when you omit the void. However, both versions with and without void are correct.
Read this answer about that matter too.

#include<stdio.h>
#include<stdlib.h>
int main(int c,char *v[])
{
int x,y;
int *num;
if(c==1)
{
printf("Usage : programName : number");
return 0;
}
num=(int *)malloc(sizeof(int));
*num=atoi(v[1]);
x=1;y=1;
while(x<=*num)
{
y=y*x;
x++;
}
printf("Factorial of %d is %d ",*num,y);
free(num);
return 0;
}

What error message do you get?
First off, declare your function factorial before main. Also, pay attention to correct indentation. Your declaration of function main is correct, by the way.

I would suggest to use also double or unsigned long for factorial computation in order to be able to compute the greater value of the factorial function.
double fact( double n)
{
if ( n == 1)
return 1;
return n*(fact(n-1));
}

A more elegant non-recursive function.
#include<stdio.h>
long long int fact(long long int);
long long int fact(long long int n){
long long int num = 1;
long long int fi = 0;
for(long long int i=2;i<=n;i++){
for(long long int j=1;j<=i;j++){
fi += num;
}
num = fi;
fi = 0;
}
return num;
}
int main(){
long long int n;
scanf("%lld",&n);
printf("%lld\n",fact(n));
return 0;
}

Related

Can you please spot the error I made in C implementation of the Karatsuba algorithm

I need to implement the karatsuba algortihm into a c code for my homework and I did my research and came up with the following code:
long int karatsuba(long int x,long int y)
{
if((x<10)||(y<10)) \\if the numbers have 1 digit, I just multiply them
return x*y;
else
{
long int a, b, c, d, ac, bd, z;
int n=uzunluk(x);
a=floor(x/ust(10, ceil(n/2)));
b=x%ust(10, ceil(n/2));;
c=floor(y/ust(10, ceil(n/2)));
d=y%ust(10, ceil(n/2));;
ac=a*c;
bd=b*d;
z=(a+b)*(c+d)-ac-bd;
long int res=ust(10, 2*ceil(n/2))*ac+ust(10, ceil(n/2))*z+bd;
return res;
}
}
int main(void)
{
printf("%ld", karatsuba(837487, 368498));
return 0;
}
ust(x, n) is the function to get the power of number x:
long int ust(long x, long n)
{
long int res=1;
int i;
for(i=0; i<n; i++)
{
res*=x;
}
return res;
}
And the uzunluk(x) gets the number of digits in the given input:
int uzunluk(long int x)
{
int lx;
while(x>0)
{
x/=10;
lx+=1;
}
return lx;
}
the problem is this code prints nothing :D
I would be glad if someone could spot the mistake I made.
So it comes out the problem was 7 digits numbers' multiplication does not result proper under the long integer identification. As I changed it to long long int, it started working properly. Thank you all for your help

Array to int and Sum of them in C

im learning C and i am a bit confused with array handling.
I have a task that asks me to sum up 2 arrays of non negative integers.
example array 1 = {1,2,3} , array 2 = {4,5,6} -> 123+456 = 579
I searched a bit for a solution on how to convert those arrays of integers to an integer, but didnt really get helpful information.
I ended up with a code:
#include <stdio.h>
int sum(int A[],int B[], int n){
int i,j,t,k;
for(i=0;i<n;i++){
t= t+A[i];
}
for(j=0;j<n;j++){
k= k+B[j];
}
return t+k;
}
int main()
{
int n = 3;
int a[n] = {1,2,3};
int b[n] = {4,5,6};
printf("%d",sum(a,b,n));
return 0;
}
But my result is 1225283 which of course is wrong.
I found a solution where people write something like "t= 10* t+A[i]" , i dont get where that "10* " comes from, but i tested it and then "t" gets "123" but if i try the same for "k" it doesnt work, returning "k" doesnt give me "456". I am a bit confused, whats the proper way of handling this problem?
Thanks for any help.
You're basically adding digits 1+2+3 instead of creating the number 123. Your code also has various other flaws, like uninitialized variables. Here is a working example:
int array2int(int A[], int n) {
int ret = 0;
for(int i=0, k=1; i<n; i++){
ret = ret + k * A[i];
k *= 10;
}
return ret;
}
int sum(int A[],int B[], int n){
return array2int(A, n) + array2int(B, n);
}
First of all, in sum function, you haven't initialized neighter t nor k but you keep summing them and use later, so every time your code is executed, you chould get different result.
On the other hand, in something like "t= 10 t+A[i]", 10 comes from basic math, where a number could be resolved as a10^0 + b10^1 +c*10^2 + .... + m * 10^n. As a result, starting from least significant digit, everytime you try to add new digit (from least to most significant), you need your multipliciant to be 10 times greater.
int sum(int A[],int B[], int n){
int i,j,t=0,k=0,ten=1;
for(i=n-1;i>=0;i--){
t += ten*A[i];
ten *= 10;
}
ten = 1; /* initialize again*/
for(j=n-1;j>=0;j--){
k += ten*B[j];
ten *= 10;
}
return t+k;
}
Something like that should work.

Factorial function only counts to 12

This factorial function starts giving wrong results with 13 and above. I have no idea why.
#include <stdio.h>
int fatorial (int p);
int main() {
int x = 13;
int test = fatorial(x);
printf("%d", test);
}
int fatorial (int p) {
if (p <= 0)
return 1;
else
return p*fatorial(p-1);
}
for x = 0, 1, 2 ...12 it prints the right result, but for 13! it prints 1932053504 which is not correct.
For x=20 it prints -210213273 for example.
I know that this is not the best way to do a factorial. Its my homework tho, it HAS to be this way.
If you try this you will get the maximum value that int can hold:
#include <stdio.h>
#include <limits.h>
int main(void)
{
printf("%d\n", INT_MAX);
}
Your code causes overflow.
You could get a few more numbers if you use a bigger type, but not by very much. You could use this:
unsigned long long fatorial (unsigned long long p) {
if (p <= 0)
return 1;
else
return p*fatorial(p-1);
}
It won't get you far though. If you want bigger than that you need to find a library for bigger integers or create some custom solution. One such library is https://gmplib.org/ but that is likely out of scope for your homework.
And btw, a condition like p <= 0 is not good. It indicates that the factorial of a negative number is always one, which is false.
It is because after 12, the result of factorial of any number exceeds the size of int.
you can try the following code:
#include<stdio.h>
int main()
{
int a[100],n,counter,temp,i;
a[0]=1;
counter=0;
printf("Enter the number: ");
scanf("%d",&n);
for(; n>=2; n--)
{
temp=0;
for(i=0; i<=counter; i++)
{
temp=(a[i]*n)+temp;
a[i]=temp%10;
temp=temp/10;
}
while(temp>0)
{
a[++counter]=temp%10;
temp=temp/10;
}
}
for(i=counter; i>=0; i--)
printf("%d",a[i]);
return 0;
}
The result of the function is too big. I think big int would work better for your purposes. Big int allows you to have bigger numbers. Also, this is what I would do.
int x = the number you want to factorialize
int ans = 1;
(Then instead of all of those functions)
for(var i = x; i > 0; i--) {
ans = ans*i;
}
System.out.println(ans);
Javascript link: https://jsfiddle.net/8gxyj913/
I need to get to 100!
100! is about 9.332622e+157. Simply using standard integer types is insufficient. 32-bit int is good to 12!. With 64-bit integer math, code could get to about 21!
Could use floating point math and give up precision.
Instead consider a string approach.

Is this factorial function from a C tutorial wrong?

I have a little programming experience in Python, and for the sake of curiosity I started to learn C, at least the very basics. In a tutorial, I found an example function for calculating a factorial, which is this:
int factorial(int x)
{
int i;
for(i=1; i < x; i++)
{
x *= i;
}
return x;
}
I also added these lines in order to see the output:
#include <stdio.h>
int main()
{
int val;
val = factorial(5);
printf("%d\n",val);
return 0;
}
Then I compiled the code with gcc factor.c -o factor.out, run and... ooops, the result is -1899959296, clearly there's something wrong.
After a couple of tries, using printf() to print both i and x, I figured out what went wrong (I think): since the condition of the for loop checks if the counter is less than x, and at each step x gets bigger and bigger, i is always less than x, so the loop keeps going on, presumably stopping when the value of x is too big (which should be related to int, I'm not very familiar yet with the various data types).
So, to "solve" the problem, I rewrote the function like this:
int factorial(int x)
{
int counter = x;
int number = x;
int i;
for (i=1; i < counter; i++)
{
number *= i;
}
return number;
}
I compiled the program, run, and the value printed is 120, which is correct.
I searched a little bit for examples of factorial functions in C, and found many solutions much better than mine, taking into account negative numbers and formats like long and whatnot, but all of them, in a way or another, seem to rely on two "main" variables, much like my solution.
So, the final question: is the example proposed wrong, or am I missing something? This really bothers me, because if such a simple example is blatantly wrong, I should question the credibility of the rest.
Yes, indeed. The original factorial function is wrong for exactly the reason you've identified. You can't use x as both the accumulator and loop limit.
In your version, one improvement I'd suggest is to get rid of counter. Since you're no longer modifying x, you don't need to save off a copy of it.
int factorial(int x)
{
int number = x;
int i;
for (i=1; i < x; i++)
{
number *= i;
}
return number;
}
You could do this without additional variables if you reverse the loop.
int factorial(int x)
{
int i;
for (i = x - 1; i > 1; i--)
{
x *= i;
}
return x;
}
I wouldn't write it this way, though. Modifying an input parameter is poor style.
I think by putting loop condition i<=x and using another variable to store factorial will correct it.
Here is the example:
int factorial(int x)
{
int i;
int fact = 1; //store factorial
for (i = 1; i <= x; i++)
{
fact *= i;
}
return fact;
}
Or you can use recursive function
int factorial(int x) {
if (x == 1)
return 1;
else
return x * factorial(x - 1);
}

Finding frequency of an integer in an array and calculating x to the nth power

I am trying to solve two different C problems and would like some help and advice in order to better understand how C works and if I'm on the right track with these.
First problem is: To write a function that counts the number of times the value (x) appears among the first (n) elements of an array and returns that count as the frequency of x in theArray. So, an example would be if the array being passed contained the values {5, 7, 23, 8, 23, 67, 23}. And n was 7 and x was 23, then it would return a value of 3 since 23 occurs 3 times within the first 7 elements of the array.
Here is what I have so far:
#include <stdio.h>
#define SIZE 20 /* just for example - function should work with array of any size */
int frequency (int theArray[], int n, int x)
{
int i;
int count = 0;
for (i = 0; i < n; i++)
{
if (theArray[i] == x)
{
count = count++;
}
}
return (count);
}
int main(void)
{
/* hard code n and x just as examples */
int n = 12; /* look through first 12 items of array */
int x = 5; /* value to find */
int numberFrequency;
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
numberFrequency = frequency (theArray[SIZE], n, x);
printf ("%i", numberFrequency);
return 0;
}
Currently I'm getting a run time error message and believe it has something to do with the for loop function.
Second problem is: Write a function that raises an integer to a positive integer power. Have the function return a long int, which represents the results of calculating x to the nth power. Do not use the C pow library function and do not use recursion!
My code so far:
#include <stdio.h>
int x_to_the_n (int x, int n)
{
int i;
long int result = 1;
if (n == 0)
{
return(result);
}
else
{
for (i = 0; i < n ; ++i)
{
/* equation here - How can I make (x*x*x*x*x*x,etc...? */
result = x*(n*x);
}
}
return (result);
}
int main(void)
{
int x =4;
int n =5;
long int result;
result = x_to_the_n (x, n);
printf ("%i", result);
return 0;
}
I can't use recursion so that is out of the question. So, I thought the next best thing would be a for loop. But I'm a little stuck in how I would go about making a for loop do (xxx*x....) based on value of (n). Any help and advice would be appreciated!
In the first problem you give an element after the array as a parameter to your function.
You define a long int array, and pass it into a function expecting an int array.
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
should be
int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
Instead of this:
numberFrequency = frequency (theArray[SIZE], n, x);
try this:
numberFrequency = frequency (theArray, n, x);
And replace:
count = count++;
with:
count++;

Resources