0

重複の可能性:
すべての桁を表示して、任意に大きな数の階乗を計算する

この質問は、ここで何千回も尋ねられる可能性があります。変更を加えて質問を繰り返します。大きな数 ( ) の階乗を計算したいmax range of the number=10^6。通常、古い値を新しい値に乗算するたびに、forループを使用します。これは小さな数には問題ありませんが、大きな数の場合はどうなりますか? ループの範囲が広がりました。Java プリミティブ データ型は、結果の大きな数値を処理できません。それらは単にオーバーフローします。クラスについては知っていましたが、この大きな出力を処理できますが、ループはここではあまり適していません。誰かが、階乗を計算するためのティック、ハックを提案してもらえますか? 以下は、少数の場合にうまく機能する簡単なプログラムです-i=1i=numberforintlongBigIntegerfor

public long getFactorial(long number) {
    long factorial = 1;
    for (long i = 1; i <= number; ++i) {
        factorial *= i;
    }
    return factorial;
}
4

4 に答える 4

10

値が 10 5565708の範囲にあることを理解してください。それだけで約 2 メガバイトのスペースを占有します。

そうは言っても、グアバ BigIntegerMath.factorial(int)はそれを処理するのに十分であり、さらに重要なことに、実際には大規模な階乗用に最適化されています.単純なループよりもはるかに優れています. for(開示:私はGuavaに貢献しています...そしてBigIntegerMath.factorial自分自身の多くを書きました。)

とは言っても、私はそれを正確に高速とは呼びません-私のベンチマークは、その範囲の階乗で平均414ミリ秒を示しています-しかし、非常に重いbignumライブラリがなければ、真に高速なソリューションはありません.そして、それらでさえ大幅に高速になるとは思いません。

それは、正確な値が必要な場合です。対数で解決できる場合は、ApachelogGamma(n+1)を使用して を取得するln(n!)か、自分で近似します。

double logFactorial = 0;
for (int i = 2; i <= n; i++) {
  logFactorial += Math.log(i);
}

多少の丸め誤差が蓄積される可能性がありますが、とにかく概算であるはずです。

于 2012-04-13T20:57:06.003 に答える
2

このような大きな値の n には、スターリングの公式と呼ばれる近似関数を使用できます。

詳細については、こちらの回答を参照してください: https://softwareengineering.stackexchange.com/questions/134968/number-of-combinations/134972#134972

于 2012-04-13T20:52:50.270 に答える
1

ガンマ関数を使用します。ガンマ(i + 1) = i!

org.apache.commons.math.specialは、Java 用にそれを提供します。

人々が通常行うことは、log(Gamma(i+1)) を計算してから対数空間で作業することです (掛け算が足し算になるなど)。

階乗をすばやく計算する他の方法を次に示します。 http://www.luschny.de/math/factorial/FastFactorialFunctions.htm

于 2012-04-13T20:55:56.393 に答える
0

BigIntegerfor を使用しますが、ループ変数で あるforfactorialのみが必要です。1000000 まで上げればいいだけです。何が問題なのですか?longii

于 2012-04-13T20:53:03.980 に答える