Hey everyone of Stack Overflow!
So I am stuck on this prompt:
"Use a loop to determine the value of n that will produce the largest n! value that could be stored in an unsigned short variable. Print out the maximum value for an unsigned short variable, the value of n that will produce the largest n! that is less than or equal to the maximum value for an unsigned short variable. NOTE: The constant USHRT_MAX contained in limits.h provides the maximum value for an unsigned short variable."
I'm guessing, for the above prompt, that it addresses why when I enter an integer such as 34 into the program, I get 0 as the output for the factorial of 34.
I have already made the code for determining the n! value when n is entered so far, but this new part has me confused.
I don't think this will help, but here is the code I have before this prompt:
#include <stdio.h>
unsigned long Factorial(unsigned int n);
int main(void)
{
int num[11],i=0,factorials[11];
printf("Please enter up to 10 integers (q to quit): ");
//Ask for integers until a 'q' is entered and store integer values entered into array 'num'
while (scanf("%u",&num[i]))
{
//Store the factorial of integers entered into array 'factorials'
factorials[i]=Factorial(num[i]);
//Print numbers out in a two column table
printf("%5u %9u\n",num[i],factorials[i]);
i++;
}
return 0;
}
//Calculates the factorial of 'n'
unsigned long Factorial(unsigned int n)
{
int nFactorial,i=1;
nFactorial=n;
while (i<n)
{
nFactorial=nFactorial*i;
i++;
}
n=nFactorial;
}
Anyways, if anyone can help out, I'd greatly appreciate it! I know this sounds like a tall order of a question, so even a pointer would help heaps!
Thanks anyone!
Cheers, Will.
EDIT: I apologize in advance if my code is difficult to read, I'm working on making it better
EDIT: I came up with this to answer the prompt so far, but it doesn't seem right. The output value is 8...
//Detemine largest max value of n
for (i=0;Factorial(i)<=USHRT_MAX;i++);
printf("The max value for an unsigned short is %u\n Max value of n: %u\n",USHRT_MAX,i-1);
return 0;
Since you're using a short, you can store the factorial sum in a larger type like unsigned long int
.
int main(void)
{
unsigned long int sum = 1;
unsigned int n;
for( n = 1; sum < USHRT_MAX; n++ ) {
sum *=n;
}
printf("%lu\n", sum);
printf("%u\n", n);
}
This is kind of cheating as there's no guarantee a long int
will be larger than a short
, but it's really likely. You can mitigate that by verifying.
assert( sizeof(unsigned short) < sizeof(unsigned long int) );
The non-cheating way is to check if you're about to overflow. You're gonna want to do this, but you can't.
USHRT_MAX >= sum * n
sum * n
will overflow. Instead, divide both sides by n
and check that.
USHRT_MAX / n >= sum
That will stop just before sum *= n
would overflow. We can verify by plugging in some numbers. USHRT_MAX = 23, n = 4 and sum = 6...
23 / 4 >= 6
5 >= 6
Note that this is integer division, so it's truncated. That's fine for our purposes.
#include <stdio.h>
#include <limits.h>
int main(void)
{
unsigned short sum = 1;
unsigned int n;
for( n = 1; (USHRT_MAX / n) >= sum; n++ ) {
sum *=n;
}
// We went one too far
n--;
printf("%u\n", sum);
printf("%u\n", n);
}