2017-02-19 4 views
0

Hey everyone of Stack Overflow! !最大符号なしショート変数プロンプトにスタック

は、だから私はこのプロンプトに貼り付けています:。

は「符号なしshort変数に格納することができ、最大のn値を生成しますnの値を決定するためにループを使用しての最大値を印刷しますunsigned short変数、unsigned short変数の最大値以下の最大n!を生成するnの値注:limits.hに含まれる定数USHRT_MAXは、unsigned 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; 
} 

、誰でも助けることができるならば、私はそれを大幅にいただければと思います!私はこれが質問の背の高い注文のように聞こえることを知っているので、ポインタでさえヒープを助けるでしょう!

ありがとうございます!

乾杯、ウィル。

EDIT:私のコードは、私が作ることに取り組んでいます読み取ることが困難である場合、私は事前に謝罪、それより良い

EDIT: は、私はこれまで、プロンプトに答えるために、この思い付いたですが、それはできませんそう思える。出力値は、あなたが短いを使用しているので、あなたがunsigned long intのような大きなタイプで階乗の和を格納することができます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!<'USHRT_MAX'」が「nを計算する必要がある」と同じではないnを見つけると言ってください。たとえば、 'USHRT_MAX'を' 2 'で除算し、その結果を '3'で除算し、その結果を' 4'で割ることで、 'n'が少なくとも4であると確信できます。分割される値が現在の結果を超えるまで続けてください。 – Peter

答えて

1

です。

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); 
} 
関連する問題