-1

C++ で階乗関数を作成しようとしましたが、10 を超える入力が正しく計算されないことがわかりました。C# を試しましたが、同じ問題に直面しました。

この再帰関数を使用して:

   int Factorial(int Number) {
        if (Number == 0) return 1;
        return Number * Factorial(Number - 1);
    }

プログラムは大きな数値に対して 0 を返し、15 や 16 などの小さな入力でも間違って計算されます。つまり、結果は Windows 電卓で得られる結果とは異なります。

4

4 に答える 4

3

これintは、 が 32 ビットに制限されており、結果が10!10 をはるかに超えると、より大きな結果が得られるためです。値が大きい場合は、結果として を使用して近似結果を得ることができますdouble。約 16 桁以上の精度が必要な場合は、多精度数学ライブラリを使用する必要があります。

を使用uint64_tすると、より多くの数が許可されますが、それでもかなり制限されます。

于 2013-06-16T18:00:56.710 に答える
1

intこれは、階乗が大きな数であり、変数に収まらないためです。あふれます。unsigned long longの代わりに を使用するとint、より大きな階乗を計算できます。

結果が正確である必要がない場合は、double も使用できます。それ以外の場合、配列に乗算を実装し、必要なだけ大きな階乗を計算できます。

C/C++ では、GMP ライブラリをお勧めします

そして、あなたが C ファミリー言語を求めたからです。Java にBigIntegerも有用な型があります。

于 2013-06-16T17:59:35.520 に答える
0

変数は、無限の数の値を保持できません。32 ビット マシンでは、intが表すことができる最大値は 2^31-1、つまり 2147483647 です。 unsigned intlongunsigned longlong long、または最大のunsigned long long. 階乗は大きな数であり、簡単にオーバーフローする可能性があります! 任意の精度が必要な場合は、GNU GMP などの bignum ライブラリを使用する必要があります。

于 2013-06-16T18:02:04.027 に答える
0

あなたの問題の理由は単純です.C++ではLong Long intで最大です。範囲は ~10^18 です。そのため、それより大きい数値を格納することはできません。そして100!158桁なので、ベクトル/配列を使用できない限り、その数値をC++/Cに格納する方法はありません

あなたは新しいプログラマーで、C++/C のみを使用しています。

次に、プログラミング目的(アルゴリズムまたはプログラミング コンテストの目的)で GMP ライブラリを使用することはお勧めしません。

独自に実装して使用できると思います..私はこれをプログラミングコンテストとアルゴリズムの問​​題で自分の目的のために使用しています.

// Shashank Jain
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#define LL long long int
using namespace std;
vector<int> fact;
void do_it(int num)
{
    int temp,carry;
    vector<int>:: iterator it;
    carry=0;
    for(it=fact.begin();it!=fact.end();it++)
    {
        temp=(*it)*num;
        temp+=carry;
        *it=temp%10;
        carry=temp/10;

    }
    if(carry!=0)
    {
        while(carry>0) 
        {       
            temp=carry%10;
            fact.push_back(temp);
            carry/=10;
        }
    }
}
int main()
{   
    int num,i,l;
    cin>>num; // enter number for which you want to get factorial
    fact.push_back(1);
    for(i=2;i<=num;i++)
        do_it(i);

    l=fact.size();  
    cout<<"The Length of factorial is: "<<l<<endl;
    for(i=l-1;i>=0;i--)
    {
        cout<<fact[i];  
    }
    cout<<endl;
    return 0;
}

Ideone でのコード リンクの実行

これにより、2000 の階乗を 1 秒未満で簡単に取得できます。または、GMPライブラリを使用できます。ただし、Google Code jam や Facebook Hacker Cup などのプログラミング コンテストでは使用できません。またはトップコーダーまたはその他の標準的なプログラミングコンテスト

于 2013-06-17T08:22:19.210 に答える