2017-02-19 48 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); 
}