我申请这个blog是为了督促自己,把自己平时的一些想法和思考结果保留下来。 本博客所有内容均为原创,如有转载请注明作者和出处

数值超过NUMBER最大表示范围的问题(三)

上一篇 / 下一篇  2006-12-15 00:00:00 / 个人分类:ORACLE

昨天同事给我出了一道简单的题——计算1阶乘到100阶乘的累加。问题似乎很简单,但是最终引出的问题并不简单。

数值超过NUMBER最大表示范围的问题(一):http://yangtingkun.itpub.net/post/468/234035

数值超过NUMBER最大表示范围的问题(二):http://yangtingkun.itpub.net/post/468/239478


,N5Lt VI,nL8j:D*g0

上文以及给出了用C外部过程的解决方案,但是使用C来解决这个问题,实在是很麻烦,需要编写OCI程序,利用MAKE文件编译成.so文件,还需要配置监听程序等一系列的复杂操作。

和上面这些额外的复杂操作形成鲜明对比的是,真正在C中进行计算的核心代码实际上只有几行,因此这里选择C外部过程感觉有点得不偿失。

那么使用JAVA外部过程是否会简单一点呢:

SQL> create or replace and compile java source named "multi_sum" as ITPUB个人空间.R]1e]}g @
2 import java.math.BigDecimal;
P(HF V8U O A,G0 3 public class multi_sum extends Object
P7Wy,V M8j0 4 {
!liwdlo3|9aGO&~D0 5 public static String multi_sum_java (int n)
3eT~hI]2J0 6 {
Y.j[+lEt&Yx0 7 BigDecimal result = new BigDecimal(0);
bO/F9quhUa N0 8 BigDecimal result_mul = new BigDecimal(1);ITPUB个人空间7Ly R9m*HHt$P3cl
9 for(int i=1;i<=n;i++)
3EJ9{4`:@+B0 10 {ITPUB个人空间8EWI WT"AH
11 result_mul = result_mul.multiply(new BigDecimal(i));ITPUB个人空间8}Rz(b4lO5tM
12 result = result.add(result_mul);
|A8?q;U+u0 13 }
(j:g {|T%N0 14 return result.unscaledValue().toString();
4x-a{+d!C@V0 15 }ITPUB个人空间%y1j"B ZrB
16 }ITPUB个人空间-I%I4Q"e\6W8Q/?
17 /

Java created.

SQL> create or replace function f_multi_sum_java(p_in in number) return varchar2 asITPUB个人空间.M.ME v6j:pa
2 language java name 'multi_sum.multi_sum_java(int) return String';
-y{5]5Mb9ZN0 3 /

Function created.

SQL> SELECT F_MULTI_SUM_JAVA(5) FROM DUAL;

F_MULTI_SUM_JAVA(5)ITPUB个人空间1lxj1t8Ns
------------------------------------------------------------------
MAbU WBJGi0153

SQL> SELECT F_MULTI_SUM_JAVA(100) FROM DUAL;

F_MULTI_SUM_JAVA(100)
'H a,m1F|Ts,`h0------------------------------------------------------------------
1t$nCM3U1ALAM{2d094269001683709979260859834124473539872070722613982672442938359305624678223479506023400294093599136466986609124347432647622826870038220556442336528920420940313

C外部过程不同,JAVA可用直接在数据库中编译、装载、运行,因此,JAVA外部过程显得比C外部过程要简单得多。

最后值得一提是,利用JAVA过程的BigDecimal对象,可以得到一个确切的数值。而在c中使用的是标准数据类型double,使用double类型只能保证前16位有效数字,后面的数值都是不准确的。

我的Java水平很低,因此自己实现的时候采用的也是double类型,这个程序是同事帮忙完善的,利用javadouble类型,仍然只能得到16位有效数字。


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar