0
votes

Write a program in C to compute the factorial of the numbers passed from the command line. The factorial must be computed in a separate function called computeFact( ) which has the following prototype: int computeFact(int,…);

#include <stdarg.h>
#include <stdio.h>
#include<stdlib.h>
int computeFact(int, ...);
int main(int argc, char *argv[]) 
{
  if (argc < 2) 
  {
    printf("Invalid!");
  } else {
    for (int i = 1; i < argc; i++)
    {
      int n = atoi(argv[i]);
      printf("Factorial of %d is %d\n", n, computeFact(n));
    }
  }
  printf("\n");./
  return 0;
}
int computeFact(int num, ...) 
{
  va_list valist;
  int fact = 1;

  va_start(valist, num);
  for (int i = 0; i < num; i++) 
  {
    int x=va_arg(valist, int);
    if(x==0)
      return 1;
    else
    {
    for(int j = 1; j <= x; j++)
       fact=fact*j;
    return fact;
    }
  }
  va_end(valist);
}

The output is as follows:

~$ ./1 1 2 3 4 5 6 7 8 9 10
Factorial of 1 is 1
Factorial of 2 is 2
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
Factorial of 6 is 720
Factorial of 7 is 5040
Factorial of 8 is 40320
Factorial of 9 is 362880
Factorial of 10 is 1

~$ ./1 0
Factorial of 0 is 1

~$ ./1 99
Factorial of 99 is 362880

~$ ./1 98
Factorial of 98 is 40320

~$ ./1 5
Factorial of 5 is 120

I think there is some error in converting string to int, as only last digit in two digit numbers is taken up for calculating factorial, but I am not able to identify what exactly to correct in my code.

2
It's interesting that this code works at all (at least for numbers < 9). What's your OS? Which compiler do you use?kol
Windows, GCC @kolSuryasnata Saha
It is very strange that your assignment specified the prototype int computeFact(int, ...), which is quite meaningless in this application. And it is even stranger that your code worked! You are fetching extra arguments that aren't there: your factorial function can theoretically be called with more than one argument, but in practice it never is, so there's always exactly 1 argument, num. Yet somehow it's working -- but purely by accident. (Oddly enough, it works on my machine, too, and for numbers greater than 9!)Steve Summit

2 Answers

3
votes

You are invoking undefined behavior by reading an argument that doesn't exist via va_arg.

It looks like you should stop using va_* macros and simply use the argument num in this case.

int computeFact(int num, ...) 
{
  int fact = 1;

  int x=num;
  if(x==0)
    return 1;
  else
  {
    for(int j = 1; j <= x; j++)
      fact=fact*j;
    return fact;
  }
}

Also be aware of the limitation of int. 99! will be 156 digits in decimal and it won't fit in the range of typical int (upto 2,147,483,647 = 2**31 - 1).

0
votes

Try below code:

int computeFact(int num, ...) 
{
  int fact = 1;

  int x = num;
  if(x==0)
    return 1;
  else
  {
    for(int value = 1; value <= x; value++)
      fact=fact*value;
    return fact;
  }
}