由于Oracle的数值类型的最大精度只有38位,因此对于高精度的数值计算就需要使用其他的方法来实现。
这篇文章利用字符串来保存高精度数值,并实现了两个字符串中数值的运算。
这篇描述两个字符串相乘。
上一篇给出了字符串表示的数值相加的函数,这一篇继续描述字符串表示数值相乘的算法。
采用代码重用的方法,利用以前处理整数乘法的基础,加上小数部分的处理。
由于包含了小数部分,一个乘法变成4个乘法的相加,因此还要利用前面一篇文章的字符串相加的函数:
SQL> create OR REPLACE FUNCTION F_STR_MULTI(P_STR1 IN VARchar2, P_STR2 IN VARchar2) RETURN VARchar2 AS 2 3 V_INTEGER_STR1 VARchar2(32767) := NVL( 4 SUBSTR(P_STR1, 1, 5 CASE INSTR(P_STR1, ’.’) WHEN 0 THEN LENGTH(P_STR1) ELSE INSTR(P_STR1, ’.’) – 1 END 6 ), 0); 7 V_INTEGER_STR2 VARchar2(32767) := NVL( 8 SUBSTR(P_STR2, 1, 9 CASE INSTR(P_STR2, ’.’) WHEN 0 THEN LENGTH(P_STR2) ELSE INSTR(P_STR2, ’.’) – 1 END 10 ), 0); 11 V_OTHER_STR1 VARchar2(32767) := CASE INSTR(P_STR1, ’.’) 12 WHEN 0 THEN NULL ELSE SUBSTR(P_STR1, INSTR(P_STR1, ’.’) + 1) END; 13 V_OTHER_STR2 VARchar2(32767) := CASE INSTR(P_STR2, ’.’) 14 WHEN 0 THEN NULL ELSE SUBSTR(P_STR2, INSTR(P_STR2, ’.’) + 1) END; 15 V_LENGTH_OTHER_1 NUMBER := NVL(LENGTH(V_OTHER_STR1), 0); 16 V_LENGTH_OTHER_2 NUMBER := NVL(LENGTH(V_OTHER_STR2), 0); 17 V_RESULT1 VARchar2(32767); 18 V_RESULT2 VARchar2(32767); 19 20 FUNCTION F_MULTI_STR(P_MUL1 IN VARchar2, P_MUL2 IN VARchar2) RETURN VARchar2 AS 21 V_LENGTH1 NUMBER DEFAULT LENGTH(P_MUL1); 22 V_LENGTH2 NUMBER DEFAULT LENGTH(P_MUL2); 23 BEGIN 24 IF V_LENGTH1 > 19 THEN 25 RETURN F_STR_ADD(F_MULTI_STR(SUBSTR(P_MUL1, 1, V_LENGTH1 – 19), P_MUL2) || LPAD(’0’, 19, ’0’), 26 F_MULTI_STR(SUBSTR(P_MUL1, V_LENGTH1 – 18), P_MUL2)); 27 ELSIF V_LENGTH2 > 19 THEN 28 RETURN F_STR_ADD(F_MULTI_STR(P_MUL1, SUBSTR(P_MUL2, 1, V_LENGTH2 – 19)) || LPAD(’0’, 19, ’0’), 29 F_MULTI_STR(P_MUL1, SUBSTR(P_MUL2, V_LENGTH2 – 18))); 30 ELSE 31 RETURN TO_NUMBER(P_MUL1) * TO_NUMBER(P_MUL2); 32 END IF; 33 END; 34 35 BEGIN 36 V_RESULT1 := F_MULTI_STR(V_INTEGER_STR1, V_OTHER_STR2); 37 V_RESULT2 := F_MULTI_STR(V_INTEGER_STR2, V_OTHER_STR1); 38 V_RESULT1 := SUBSTR(V_RESULT1, 1, LENGTH(V_RESULT1) – V_LENGTH_OTHER_2) 39 || ’.’ 40 || SUBSTR(V_RESULT1, – V_LENGTH_OTHER_2); 41 V_RESULT2 := SUBSTR(V_RESULT2, 1, LENGTH(V_RESULT2) – V_LENGTH_OTHER_1) 42 || ’.’ 43 || SUBSTR(V_RESULT2, – V_LENGTH_OTHER_1); 44 RETURN LTRIM(RTRIM(RTRIM 45 ( 46 F_STR_ADD 47 ( 48 F_STR_ADD 49 ( 50 F_MULTI_STR(V_INTEGER_STR1, V_INTEGER_STR2) 51 || ’.’ 52 || LPAD( 53 F_MULTI_STR(V_OTHER_STR1, V_OTHER_STR2), 54 V_LENGTH_OTHER_1 + V_LENGTH_OTHER_2, 55 ’0’), 56 V_RESULT1 57 ), 58 V_RESULT2 59 ), 60 ’0’), ’.’), ’0’ 61 ); 62 END; 63 / 函数已创建。 |
下面简单测试一下函数的功能:
SQL> select F_STR_MULTI(’12345678900987654321’, ’555’) FROM DUAL; F_STR_MULTI(’12345678900987654321’,’555’) ———————————————————————— 6851851790048148148155 SQL> select F_STR_MULTI(’1.2345678900987654321’, ’555’) FROM DUAL; F_STR_MULTI(’1.2345678900987654321’,’555’) ———————————————————————— 685.1851790048148148155 SQL> select F_STR_MULTI(’0.12345678900987654321’, ’0.00555’) FROM DUAL; F_STR_MULTI(’0.12345678900987654321’,’0.00555’) ———————————————————————— .0006851851790048148148155 SQL> select F_STR_MULTI(’6.125’, ’4.8’) FROM DUAL; F_STR_MULTI(’6.125’,’4.8’) ———————————————————————— 29.4 SQL> select 12345678900987654321*555 FROM DUAL; 12345678900987654321*555 ———————— 6.8519E+21 |
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
作者
相关推荐
-
Collaborate 18大会:了解甲骨文云数据库和应用的进展
在Collaborate 18大会即将举行时,我们会发现,甲骨文用户社区的技术变化会略高于平常水平。 由独立甲 […]
-
甲骨文自治数据库亮相 带来云计算新希望
早前甲骨文还不在云计算公司之列,而现在该公司正在迅速弥补其失去的时间。甲骨文的云计算核心是甲骨文自治数据库(O […]
-
2017年12月数据库流行度排行榜 定格岁末排名瞬间
数据库知识网站DB-engines最近更新的2017年12月份数据库流行度排名情况是否能提供更多的看点呢?TechTarget数据库网站将与您分享12月份的榜单排名情况,让我们拭目以待。
-
2017年11月数据库流行度排行榜 半数以上数据库积分减少
数据库知识网站DB-engines更新了2016年11月份的数据库流行度排行榜。TechTarget数据库网站将与您一同关注11月份的榜单排名情况。