2016-04-12 7 views
1

私は大きな数字linkの階乗を計算するには、次の機能を以下の午前、と私はいくつかのものが起こっている理由をもう少し理解したいと思います(長い数の階乗を計算)...中止トラップ:6

#include<stdio.h> 
#define MAX 10000 
void factorialof(int); 
void multiply(int); 
int length = 0; 
int fact[MAX]; 

int main(){ 
    int num; 
    int i; 

    printf("Enter any integer number : "); 
    scanf("%d",&num); 

    fact[0]=1; 

    factorialof(num); 

    printf("Factorial is : "); 
    for(i=length;i>=0;i--){ 
     printf("%d",fact[i]); 
    } 
    return 0; 
} 

void factorialof(int num){ 
    int i; 
    for(i=2;i<=num;i++){ 
     multiply(i); 
    } 
} 
void multiply(int num){ 
    long i,r=0; 
    int arr[MAX]; 
    for(i=0;i<=length;i++){ 
       arr[i]=fact[i]; 
     } 

    for(i=0;i<=length;i++){ 
     fact[i] = (arr[i]*num + r)%10; 
     r = (arr[i]*num + r)/10; 
     //printf("%d ",r); 
    } 
    if(r!=0){ 
     while(r!=0){ 
      fact[i]=r%10; 
      r= r/10; 
      i++; 
     } 
    } 
    length = i-1; 
} 

私の質問は:

  1. MAX定数の本当の意味は何ですか?それが大きいか小さいかはどういう意味ですか?
  2. 私はMAX = 10000(この例のような)があれば、最大3250を計算できることを知りました! 3251と一緒に試してみたら!私は 'Abort trap:6'というメッセージを受け取る。なぜその番号ですか?それはどこから来たのですか?
  3. フラグ-m32を指定して32ビットマシン用にこのコードをコンパイルすると、どちらの違いがありますか? 64ビットと同じように動作しますか?

ありがとう!

答えて

0

スコット・ハンターが指摘するように、MAXは、プログラムがスペースを使い果たす前に、結果で起こり得る最大桁数情報を意味し、factarrアレイ内の要素の最大数です。

このコードでは、配列宣言にMAXしか使用していません。ここでは、MAXを使用して、それらの配列の終わりを超えてメモリから読み書きしようとしているかどうかを判断しません。これはBad Thing™です。あなたの "Abort trap:6"エラーは3251を計算しようとしているのでほとんど確実に発生しています!正確には:arrfactの大きすぎるインデックスを使用しています。私が使用

printf("Factorial requires %d digits.\n", length + 1); 

注:

は、あなたがこのようなもので mainに既存の printfのコールを(20,000、例えば) MAXを増やすと置き換えることができ、与えられた階乗のために必要な桁数を表示するには length + 1 lengthは数字の桁数ではなく、結果の最上位桁を含む factの配列位置のインデックスです。私は3251を計算しようとする!、出力は次のとおりです。

Factorial requires 10008 digits. 

これは万のデフォルトMAX値とfactに利用できる持っているより8桁以上です。プログラムロジックがアレイ内の割り当てられたスペースを超えれば、その動作は未定義です。 "Abort trap:6."というエラーが表示されることがあります。

興味深いことに、私が3250を計算しようとすると、ここに出力があります!:まだMAXは万に設定されているときに、プログラムが確実に動作するのは、あまりにも多くのですが、その事実はあなたのプログラムが3250を計算することを

Factorial requires 10005 digits. 

!成功したかもしれないが、それは未定義の行動の性質である:おそらくあなたのプログラムは正しい結果を生み出し、おそらくクラッシュし、ロシアの目標に対して自覚してミサイルを発射するかもしれない(because it knows that the Russian counterattack will eliminate its enemies over here)。このようなコーディングは良い考えではありません。計算を完了するために使用できる以上のスペースがプログラムに必要な場合は、処理を続行するのではなく、適切なエラーメッセージを表示して停止する必要があります。

+0

ありがとう。だから、 "Abort trap"を避けるために、どちらが "良い実装"になるのだろうか。階乗を計算する前に、何桁の数字を受け取ることができるのですか?だから私にエラーを与える数字を処理するのを避けるために... –

+0

最も簡単なアプローチは、あなたのすべての配列の書き込みがあるので、 'multiply'関数にいくつかの境界チェックを入れることです。関数の最初で、 'length> = MAX'なら問題あり、' while'ループの最上位で 'i> = MAX'なら問題あります。たとえば、関数が 'void'ではなく' bool'を返すようにして、計算が成功したかどうかを示すことで、問題を示すことができます。 –

+0

他のオプションは、固定長配列ではなく、より多くの領域が必要になるほどデータ構造体を使用するか、値が高すぎる値を入力した場合にユーザーにすぐに通知する入力検証を記述することです。 (適切な制限を自分で計算し、それを別の定数として含めるか、またはn!の小数点以下桁数を返す関数f(n)を派生させなければならないでしょう) –

0
  1. MAXは、factおよびarrの要素の数です。索引> = MAXの要素にアクセスしようとすると悪いことになります。
  2. エラーメッセージは、使用している環境に固有のものであることがよくあります。詳細については説明していません。
  3. これらは同じではありませんが、差異(たとえばポインタのサイズ)は、このコードにはっきりと影響しません。
関連する問題