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 的值

试试 binary_double 数据类型,它最多可以处理 1.79769313486231E+308: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 上,它将在一秒钟内计算多达 20,000 个。http://sqlfiddle.com/#!4/007bd/58

于 2013-06-17T12:33:30.427 回答