2

OracleのExcelシートからいくつかの式を複製しようとしています。Excelシートでは、式は次のとおりです。

LN(FACT(n))

ただし、n=170 まで取得すると、数値が大きすぎるためにエラーが返されることがわかりました。次の式を使用すると、この問題を回避できることがわかりました。

GAMMALN(n+1)

これは同じ結果を返すようで、非常に大きな数を処理できます。

これをOracleで複製しようとしていますが、同じ問題が発生しています.PLSQLで階乗を計算しようとすると、83の任意の数を計算しようとすると失敗します。これを行う方法はありますか? PLSQLで?非常に大きな数の階乗を計算するか、GAMMALN 関数を再現しますか?

階乗関数のコードは次のとおりです。前に述べたように、83 を超える値を入力しようとすると失敗します。

create or replace
FUNCTION FACTORIAL(X IN INTEGER) RETURN NUMBER AS
  FACT_VALUE NUMBER := 1;
BEGIN

  FOR I IN 1..X LOOP
    FACT_VALUE := FACT_VALUE * I;
  END LOOP;

  RETURN FACT_VALUE;
END;

ありがとう

アップデート

多くの数を掛け合わせた対数はすべての対数の合計に等しいという David Aldridge の提案のおかげで、私は大きな数に対して機能する PLSQL 関数を思いつきました。

create or replace
FUNCTION LN_FACTORIAL(X IN INTEGER) RETURN NUMBER AS
  FACT_VALUE NUMBER := 0;
  TMP_VAL NUMBER;
BEGIN

  FOR I IN 1..X LOOP
    TMP_VAL := LN(I);
    FACT_VALUE := FACT_VALUE + TMP_VAL;
  END LOOP;


  RETURN FACT_VALUE;
END;

更新 2

この関数は正常に機能しますが、私が行っていた操作では、この計算を多数に対して何度も行う必要があることがわかりました。したがって、上記のアプローチは、何度も解決するのに非常に長い時間がかかりました。最終的にたどり着いた解決策は、上記の関数の結果を使用して、0 ~ 200,000 のすべての数値の結果をテーブルに入力することでした。次に、階乗が必要になったときに、テーブルをクエリするだけで、はるかに高速になります。

4

1 に答える 1

4

Number には 1.0 x 10^126 までの値が格納されますが、1.0 x 10^126 は含まれません。

最大 1.79769313486231E+308 を処理する binary_double データ型を試してみてください: http://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#autoId10

それ以外の場合、多くの数値を掛け合わせた対数は、すべての対数の合計と同じであることを思い出すようです。そうであれば、コードを簡単に変更する必要があります。

実際、純粋な Oracle SQL でこれを行うことができ、はるかに高速になります。

select sum(ln(rownum)) ln_fact
from dual
connect by level <= 7;

SQLFiddle では、1 秒強で最大 20,000 を計算します。http://sqlfiddle.com/#!4/007bd/58

于 2013-06-17T12:33:30.427 に答える