停留在最大无符号短变量提示

Posted

技术标签:

【中文标题】停留在最大无符号短变量提示【英文标题】:Stuck on maximum unsigned short variable prompt 【发布时间】:2017-02-19 00:54:14 【问题描述】:

大家好 Stack Overflow!

所以我被这个提示卡住了:

"使用循环来确定将产生最大 n 的 n 值!可以存储在 unsigned short 变量中的值。打印出 unsigned short 变量的最大值,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;

【问题讨论】:

在无符号整数和有符号整数之间切换时会遇到一堆类型问题。打开警告 (-Wall),修复它们,看看是否有帮助。另请注意,无需提示或使用数组。 34 的阶乘为 295232799039604140847618609643520000000。最大无符号短值通常为 65535。调整您的期望。 说“找到一个满足 n 的 n!USHRT_MAX”与说“有必要计算 n!”不同。例如,通过将USHRT_MAX 除以2,然后将其结果除以3,再将其结果除以4,我可以自信地说n 至少是4。继续下去,直到被除的值超过当前结果。 【参考方案1】:

由于您使用的是short,您可以将阶乘和存储在更大的类型中,例如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 和 sum = 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);

【讨论】:

以上是关于停留在最大无符号短变量提示的主要内容,如果未能解决你的问题,请参考以下文章

C语言里怎样理解长整型 短整型 和无符号型变量和常量?

有符号和无符号整型数据溢出问题

将“无符号字符”数组转换为“无符号短”数组的有效方法是啥?

在python中解压无符号短

当我想写出无符号短值时获取有符号短值

工业物联网网关变量的数据类型