昨天同事给我出了一道简单的题——计算1阶乘到100阶乘的累加。问题似乎很简单,但是最终引出的问题并不简单。
刚开始觉得问题很简单,写了一个简单的函数:
SQL> CREATE OR REPLACE FUNCTION F_SUM_MULTI(P_IN IN NUMBER) RETURN NUMBER AS
2 V_RESULT_MULTI NUMBER DEFAULT 1;
3 V_RESULT NUMBER DEFAULT 0;
4 BEGIN
5 FOR I IN 1..P_IN LOOP
6 V_RESULT_MULTI := V_RESULT_MULTI * I;
7 V_RESULT := V_RESULT V_RESULT_MULTI;
8 END LOOP;
9 RETURN V_RESULT;
10 END;
11 /
函数已创建。
SQL> SELECT F_SUM_MULTI(5) FROM DUAL;
F_SUM_MULTI(5)
--------------
153
代码很简单,功能也已经实现了。但是,问题并不想我想的这么简单。
SQL> SELECT F_SUM_MULTI(100) FROM DUAL;
F_SUM_MULTI(100)
----------------
~
奇怪,输出结果为什么会是~呢?莫非是超过了NUMBER能表示的最大的范围?
SQL> SELECT F_SUM_MULTI(83) FROM DUAL;
F_SUM_MULTI(83)
---------------
3.994E 124
SQL> SELECT F_SUM_MULTI(84) FROM DUAL;
F_SUM_MULTI(84)
---------------
~
果然是超过了NUMBER能表示的最大的范围。NUMBER类型能表达的最大值是9.9999999999999999999999999999999999*10E125。以前还从没有碰到过超出Oracle最大处理范围的情况,也一直没有想到过会碰到超出最大精度。看来阶乘不愧是结果增长最迅速的操作。
由于超过了Oracle能处理的最大值,Oracle已经很难处理这个问题了。莫非已经没有办法来处理这个问题了?(待续)