2017-02-19 19 views
0

안녕하세요 스택 오버플로 모두! !최대 부호없는 짧은 변수 프롬프트에 갇혀

은 그래서 나는이 메시지에 붙어있다 :.

는 "부호없는 짧은 변수에 저장 될 수있는 최대의 N 값을 생성합니다 n의 값을 결정하기 위해 루프를 사용하여 최대 값에서 인쇄 unsigned short 변수, unsigned short 변수의 최대 값보다 작거나 같은 가장 큰 n을 생성하는 n 값 참고 : limits.h에 포함 된 상수 USHRT_MAX는 부호없는 short 변하기 쉬운."

나는 내가이 프로그램에 정수 등 (34)를 입력 할 때, 나는 이미 만든 34

의 계승에 대한 출력으로 0을 얻을 이유를 해결할 수 있음을, 위의 프롬프트, 추측하고있어 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; 
} 

어쨌든, 나는 그것을 대단히 감사하겠습니다 : 여기이 도움이 될 것입니다 생각하지 않지만

내가이 프롬프트가 나타나기 전에이 코드입니다! 나는이 질문의 키가 큰 순서처럼 들린다. 그래서 심지어 포인터는 힙을 도울 것이다.

감사합니다.

환호, 윌.

편집 : 내 코드는, 내가 만드는 중이 야 읽기 어려운 경우 내가 미리 사과 더 잘

편집 : 는 지금까지 프롬프트에 응답이 함께했다하지만, 그렇지 않습니다 좋아 보인다. 당신이 짧은을 사용하고 있기 때문에 출력 값이

//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! <'USHRT_MAX'"가 "n을 계산할 필요가있다"고 말하는 것과 같지 않습니다. 예를 들어'USHRT_MAX'를'2 '로 나누고 그 결과를'3'으로 나누고 그 결과를'4'로 나눔으로써'n'이 적어도'4'라고 말할 수 있습니다. 분할되는 값이 현재 결과를 초과 할 때까지 계속 진행하십시오. – Peter

답변

1

... 8, 당신은 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 intshort보다 클 것이라는 보장이 없다 같은 부정 행위의 종류이지만, 정말 가능성이 높습니다. 확인을 통해이를 완화 할 수 있습니다.

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