LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Factorials in C (https://www.linuxquestions.org/questions/programming-9/factorials-in-c-766947/)

Dogs 11-04-2009 09:07 PM

Factorials in C
 
I'm trying to make a program that will complete the factorial of an entered number.
I have partial success right now, but there's a peculiar instance taking place.

So..

#include <stdio.h>

int main()
{
.int a, i;
.i = 1;
.a = 10;
.while(i < 10)
...{
....a = a * i; // I was initially using a *= i, but the same issue was present.
....i = i + 1; // same issue
...}
.printf("%d\n", a);
}


This code will do the factorial, but

while(i < a) will result in a huge negative number. this prevents me from initially being able to scanf("%d", &a); to get the value for a, and having the rest of the code yield a!.

A quick workaround I thought up was a = 10, so while(i < a) (whereas a has been assigned the value of 10) I still get the wrong answer.

There's obviously something I'm missing here with the comparison of i and a.

note: I initially tried building my own factorial function by

int factorialtest(int x)
{
.int i;
.for(i = 1; i < x; i++)
...x *= i;
...return x;
}

but the same huge negative number was present when printing the results from the main function

int a, b;
scanf("%d",&a);
b = factorialtest(a); when a was 10, or any other number.

johnsfine 11-04-2009 09:19 PM

Quote:

Originally Posted by Dogs (Post 3745132)
I'm trying to make a program that will factor an entered number.

Factor a number has a very different meaning from compute the factorial of the number. You're likely to confuse some of the people who might have given you help by phrasing that incorrectly.

Quote:

There's obviously something I'm missing here with the comparison of i and a.
Not with the comparison but with a more basic concept.

You have designed a version of factorial that manipulates three quantities:

1) The entered number, which is the upper limit at which the counter should stop counting
2) The counter, which counts up from 1 to that upper limit
3) The product of all the counter values you have used so far, which will be the result at the end of the loop.

You have just two variables for the three quantities, so you are confusing yourself about what each variable is doing at any given point in the code.

To keep your existing basic design, you need three variables to hold the three quantities. When doing so, be careful of the initial value of the variable that holds the product of all the values you have multiplied so far. What do you think that should start out as before you have multiplied anything?

If you want to use just two variables instead of three, the trick is to count backwards. Then the entered number and the counter can share one variable between them. Either way, the running product needs its own variable.

I am intentionally giving you concepts instead of corrected code and I hope other programmers who might join this thread will respect the homework policy and do the same. You have made a start, but not enough of a start that directly correcting your code would be legitimate help. At this point correcting your code would be doing your homework for you.

Also, if you post further code, please learn how to use code tags to make the forum software preserve the indenting. Your kludge to preserve indenting was a worthy effort since I assume you never heard of code tags. But the right way is with code tags.

Dogs 11-04-2009 09:39 PM

Thanks for the hint =)

Also, I have no formal training in anything regarding C, and only slightly more than that regarding math, so my terminology only goes so far.

I'll update this post in a bit after I mess with it for another couple of hours.

Codetag test = updated

Code:


#include <stdio.h>

int main()
{
 int a;
 int c;
 int b;
 printf("Enter a\n");
 scanf("%d",&a);
 c = a;
 for(b = 1; b < a; b++)
    {c *= b;}
    printf("c = %d\n", c);
}

This will work up to a = 12, but 13+ is wrong. Now I'm wondering if data type specification is important, but I tried long int c; and printf("%ld\n",c); and had the same results.


Also, as a increases to 20+, the result is quite interesting. In some instances, odd numbers yield a positive result, and even yields an negative result, in some cases, the inverse is true, and in other cases (30,31) 30 yields a larger number than 31, and for (32,33) the results are the same. Even more interesting is that 34 yields 0.

ta0kira 11-04-2009 09:46 PM

What about tgamma(a+1)?
Kevin Barry

tacorama 11-04-2009 10:37 PM

Dogs,
The while loop isnt going for 10 loops like you think it is, its going many more!

you set a=10 initially and you only want it to do the while comparision 10 times, but each time in the while loop, 'a' gets bigger and bigger far beyond ten, so 'i' will always be less than the forever increasing 'a' until 'a' overflows it's type and goes negative - terminating the while loop, and leaving 'a' negative.

to solve this issue, make a copy of 'a' prior to going into the while loop - lets call it 'maxloop'. then the code may look like this.
Code:

#include <stdio.h>

int main()
{
 int a, i, maxloop;
 i = 1;
 a = 10;
 maxloop = a;
 while(i < maxloop)
  {
  a = a * i; // now you can use a* = i if you want
  i = i + 1;
  }
 printf("%d\n", a);
}


i hope this helps.

Dogs 11-04-2009 10:45 PM

Quote:

Originally Posted by ta0kira (Post 3745160)
What about tgamma(a+1)?
Kevin Barry

I could include math.h, but this exercise is more for understanding how it works, than for doing what I want it to.

@Tacorama - You posted that right after I updated the last post I made. That code works up to a = 12, but after that come interesting results that aren't the answer I'm looking for.

Code:

#include <stdio.h>

int main()
{
 int c;
 long unsigned int a;
 int b;
 printf("Enter a\n");
 scanf("%lu",&a);
 c = a;
 b = 1;
 while(b < c)
      {a *= b;
      b = b+1;}
 printf("c = %lu\n", a);
}

Wikipedia says something that could explain what's going on here..
http://en.wikipedia.org/wiki/Factorial
Quote:

The values 12! and 20! are the largest factorials that can be stored in, respectively, the 32 bit and 64 bit integers commonly used in personal computers.
Mine, of course, is 32 bit.

tacorama 11-04-2009 11:39 PM

Dogs,
I dunno how high you need to go, but if its larger than any of the data types you can use, then may you can make your own array of say ints or even ram with 'malloc', then write your own extended math functions to effectively regroup into higher value array positions, that way you could evaluate something like 413!

Dogs 11-05-2009 12:14 AM

Quote:

Originally Posted by tacorama (Post 3745239)
Dogs,
I dunno how high you need to go, but if its larger than any of the data types you can use, then may you can make your own array of say ints or even ram with 'malloc', then write your own extended math functions to effectively regroup into higher value array positions, that way you could evaluate something like 413!

Cool. I was wondering if arrays might be useful to push past 12!, and indeed, regardless of whether or not they were, I was bound to try anyway =)

ETA - I need to go as far as I can, because I can.

jheengut 11-05-2009 12:36 AM

holla
 
check out for gmp (GNU multiple precision arithmetic library)
it may help

smeezekitty 11-05-2009 08:39 PM

try long

Dan04 11-05-2009 11:19 PM

Quote:

Originally Posted by smeezekitty (Post 3746444)
try long

Won't help on a 32-bit machine.

If an approximate answer is OK, you can use double.


All times are GMT -5. The time now is 02:46 AM.