WEB开发网
开发学院数据库Oracle 利用字符串实现高精度数值运算 阅读

利用字符串实现高精度数值运算

 2008-08-27 12:43:53 来源:WEB开发网   
核心提示:由于Oracle的数值类型的最大精度只有38位,因此对于高精度的数值计算就需要使用其他的方法来实现,利用字符串实现高精度数值运算, 这篇文章利用字符串来保存高精度数值,并实现了两个字符串中数值的运算,分别对整数部分和小数部分进行运算,并最终将结果合并起来即可,这篇描述两个字符串相加,其实在以前处理超大数值的时候

由于Oracle的数值类型的最大精度只有38位,因此对于高精度的数值计算就需要使用其他的方法来实现。

这篇文章利用字符串来保存高精度数值,并实现了两个字符串中数值的运算。

这篇描述两个字符串相加。

其实在以前处理超大数值的时候,写过一个字符串相加的函数,不过当时这个函数只是处理正整数的相加,没有考虑小数的情况。详细描述可以参考:http://yangtingkun.itpub.net/post/468/241044

当前面临的问题则主要是小数精度的问题。不过这并不影响对原有代码的重用,只需要在原有的代码外面嵌套一层,分别对整数部分和小数部分进行运算,并最终将结果合并起来即可。

   SQL>CREATEORREPLACEFUNCTIONF_STR_ADD(P_STR1INVARCHAR2,P_STR2INVARCHAR2)RETURNVARCHAR2AS
2V_INTEGER_STR1VARCHAR2(32767):=NVL(
3SUBSTR(P_STR1,1,
4CASEINSTR(P_STR1,'.')WHEN0THENLENGTH(P_STR1)ELSEINSTR(P_STR1,'.')-1END
5),0);
6V_INTEGER_STR2VARCHAR2(32767):=NVL(
7SUBSTR(P_STR2,1,
8CASEINSTR(P_STR2,'.')WHEN0THENLENGTH(P_STR2)ELSEINSTR(P_STR2,'.')-1END
9),0);
10V_OTHER_STR1VARCHAR2(32767):=CASEINSTR(P_STR1,'.')
11WHEN0THENNULLELSESUBSTR(P_STR1,INSTR(P_STR1,'.')+1)END;
12V_OTHER_STR2VARCHAR2(32767):=CASEINSTR(P_STR2,'.')
13WHEN0THENNULLELSESUBSTR(P_STR2,INSTR(P_STR2,'.')+1)END;
14V_LENGTH_OTHER_1NUMBER:=NVL(LENGTH(V_OTHER_STR1),0);
15V_LENGTH_OTHER_2NUMBER:=NVL(LENGTH(V_OTHER_STR2),0);
16V_RESULTVARCHAR2(32767);
17
18FUNCTIONF_ADD_STR(P_ADD1INVARCHAR2,P_ADD2INVARCHAR2)RETURNVARCHAR2AS
19V_LENGTH1NUMBERDEFAULTLENGTH(P_ADD1);
20V_LENGTH2NUMBERDEFAULTLENGTH(P_ADD2);
21BEGIN
22IFV_LENGTH1>37THEN
23RETURN
24F_ADD_STR
25(
26SUBSTR(P_ADD1,1,V_LENGTH1-37),
27NVL
28(
29SUBSTR
30(
31F_ADD_STR(SUBSTR(P_ADD1,V_LENGTH1-36),P_ADD2),
321,
33LENGTH(F_ADD_STR(SUBSTR(P_ADD1,V_LENGTH1-36),P_ADD2))-37
34),
35'0'
36)
37)||SUBSTR(F_ADD_STR(SUBSTR(P_ADD1,V_LENGTH1-36),P_ADD2),-37);
38ELSIFV_LENGTH2>37THEN
39RETURN
40F_ADD_STR
41(
42NVL
43(
44SUBSTR
45(
46F_ADD_STR(P_ADD1,SUBSTR(P_ADD2,V_LENGTH2-36)),
471,
48LENGTH(F_ADD_STR(P_ADD1,SUBSTR(P_ADD2,V_LENGTH2-36)))-37
49),
50'0'
51),
52SUBSTR(P_ADD2,1,V_LENGTH2-37)
53)
54||SUBSTR(F_ADD_STR(P_ADD1,SUBSTR(P_ADD2,V_LENGTH2-36)),-37);
55ELSE
56RETURN
57LTRIM
58(
59TO_CHAR
60(
61TO_NUMBER(P_ADD1)+TO_NUMBER(P_ADD2),
62RPAD
63(
64'0',
65GREATEST(V_LENGTH1,V_LENGTH2,LENGTH(TO_NUMBER(P_ADD1)+TO_NUMBER(P_ADD2))),
66'9'
67)
68)
69);
70ENDIF;
71END;
72
73BEGIN
74IFV_LENGTH_OTHER_1>=V_LENGTH_OTHER_2THEN
75V_RESULT:=F_ADD_STR
76(V_OTHER_STR1,
77V_OTHER_STR2||LPAD('0',V_LENGTH_OTHER_1-V_LENGTH_OTHER_2,'0'));
78ELSE
79V_RESULT:=F_ADD_STR
80(V_OTHER_STR1||LPAD('0',V_LENGTH_OTHER_2-V_LENGTH_OTHER_1,'0'),
81V_OTHER_STR2);
82ENDIF;
83
84IFLENGTH(V_RESULT)>GREATEST(V_LENGTH_OTHER_1,V_LENGTH_OTHER_2)THEN
85RETURNLTRIM(RTRIM(RTRIM(
86F_ADD_STR
87(F_ADD_STR(V_INTEGER_STR1,V_INTEGER_STR2),1)
88||'.'||SUBSTR(V_RESULT,2),
89'0'),'.'),'0');
90ELSE
91RETURNLTRIM(RTRIM(RTRIM(
92F_ADD_STR(V_INTEGER_STR1,V_INTEGER_STR2)
93||'.'||V_RESULT,
94'0'),'.'),'0');
95ENDIF;
96END;
97/
函数已创建。

1 2  下一页

Tags:利用 字符串 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接