2017-02-19 36 views
0

嘿大家堆栈溢出!卡住最大无符号短变量提示

所以,我被困在此提示:!

“使用循环来确定n的值,这将产生一个可以被存储在一个无符号短变量最大的n个值打印出来的最大值一个无符号的短变量,n的值将产生最大的n!小于或等于无符号的短变量的最大值注意:包含在limits.h中的常量USHRT_MAX提供了无符号短整数的最大值变量。”

我猜测,对于上面的提示,它解决为什么当我输入一个整数,如34到程序,我得到0作为输出的34.

我已阶乘用于确定n!的代码当n输入到目前为止的值,但这个新的部分让我感到困惑。

我不认为这会有所帮助,但这里是我此行之前有代码:

#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; 
} 

不管怎么说,如果有人能帮忙,我会非常感激!我知道这听起来像是一个很高的问题,所以即使是一个指针也会帮助堆!

谢谢大家!

干杯,威尔。

编辑:我提前道歉,如果我的代码是难以阅读,我正在努力使之更好

编辑: 我想出了这个回答提示,到目前为止,但它不似乎是对的。输出值是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; 
+1

你有一堆类型的问题之间切换无符号和有符号整数。打开警告('-Wall'),修复它们,看看是否有帮助。还要注意,不需要提示或使用数组。 – Schwern

+1

34的阶乘是295232799039604140847618609643520000000.最大未签名短期值通常为65535.调整您的期望值。 –

+1

说“找到一个n,使得n!<'USHRT_MAX'”与说“有必要计算n!'”不同。例如,通过将USHRT_MAX除以2,然后将结果除以3,并将结果除以4,我可以自信地说'n'至少是'4'。只要继续下去,直到分值超过当前结果。 – Peter

回答

1

由于您使用的是短,你可以存储在像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); 
} 

这是一种欺骗,因为没有保证一个long int会比short大的,但它确实有可能。您可以通过验证来减轻这一点。

assert(sizeof(unsigned short) < sizeof(unsigned long int)); 

非作弊的方法是检查,如果你即将溢出。你会想要做到这一点,但你不能。

USHRT_MAX >= sum * n 

sum * n会溢出。相反,分两边n并检查。

USHRT_MAX/n >= sum 

这将停止之前sum *= n会溢出。我们可以通过插入一些数字来验证。 USHRT_MAX = 23,N = 4,总和= 6 ...

23/4 >= 6 
5 >= 6 

注意,这是整数除法,因此它截断。这对我们的目的很好。

#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); 
}