我正在尝试在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;
由于
感谢大卫·奥尔德里奇的建议,即大量数字的对数乘以一起等于所有日志的总和,我想出了一个适用于大数的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;
我发现虽然这个功能运行正常但我正在进行的操作需要在大数字上多次完成这个计算。因此,上述方法需要很长时间才能完成多次。我最终得到的解决方案是使用上面函数的结果填充一个表,其结果为0-200,000。然后,当我需要阶乘时,我只是查询表,这要快得多。
答案 0 :(得分:4)
数字将存储最多但不包括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