4

数値66の階乗値を取得しようとしていますが、メソッドの結果は0になります。しかし、 5の階乗を取得しようとすると、出力120になります。誰か教えてもらえますか?

 public static int factorial(int n)
 {
            if (n == 1)
                return n;
            return n * factorial(n - 1);
 }
4

8 に答える 8

6

確かに-階乗は非常に大きく、非常に速くなります。あなたはintの境界を非常に速くオーバーフローしています...そしてある時点で、オーバーフローを0にするのに十分な係数を掛けて、値を永久に0に保ちます。

グーグルのクイック検索によると、66階乗は5.44344939×10 92intであり、これは処理できる量よりもかなり多く、さらにはlongまたはdecimalです。あなたはそれを処理することができますdouble-あなたは膨大な量の精度を失うでしょう、そしてそれは本当にすぐに蓄積するでしょう、しかし少なくともそれはオーバーフローしません...

于 2010-11-17T08:29:06.820 に答える
4

66!に適合しませんint。を使用しBigIntegerます。

于 2010-11-17T08:30:17.320 に答える
4

メソッドがオーバーフローします。次の例を参照してください。

static void Main(string[] args)
{
    Console.WriteLine(factorial(66));
}

public static int factorial(int n)
{
    if (n == 1)
        return n;

    var result = n * factorial(n - 1);

    Console.WriteLine("{0} : {1}", n, result);

    return result;
}

この例では、各反復の結果が出力されます。

ある時点で結果がになり0、これはその時点以降のすべての反復がになることを意味しますn * 0

を使ってみることができますBigInteger。これにより、正しい結果が得られます。C#での階乗の計算には、これに関する詳細情報が含まれています。

于 2010-11-17T08:32:22.643 に答える
2

問題は、66の階乗がに収まるように大きくなる方法であるということintです。に収まるように大きくすることもできると思いますlong

例としてfactorial(20)2432902008176640000

于 2010-11-17T08:29:52.583 に答える
2

50の階乗は3.0414093202×1064であり、intに含めることができるものをすでに実行しています。

longまたはこれに使用BigIntegerします。

于 2010-11-17T08:31:48.380 に答える
1

数値オーバーフローが発生します、66!〜= 5e92は、int缶が処理できるよりもはるかに大きいです。また、階乗はforループを使用してより適切に計算されます。

于 2010-11-17T08:29:19.893 に答える
1

階乗が整数に収まる最大の数は約13または14です...longに切り替えると、正しく思い出せば18または19になります。大きな数の調停を希望する場合は、独自の大きな算術ライブラリを作成するか、既存のライブラリを使用する必要があります:)

于 2010-11-17T08:31:08.457 に答える
0

適切なデータ型を使用する必要があります。

この場合、Big Integerデータ型は、数値が実際に大きくなる速度として最もよくわかります。

このデータ型の使用方法は次のとおりです。

pic1

プロジェクトを右クリックし、[参照の追加]メニューを選択します。

pic2

system.numericsライブラリを探して追加します。

pic3

次に、コードにusing句を追加します。

pic4

そして、通常どおり、キーワードを使用して変数を初期化できます。

于 2017-11-21T10:53:35.453 に答える