利用字串實現高精度數值運算(二)
由於Oracle的數值型別的最大精度只有38位,因此對於高精度的數值計算就需要使用其他的方法來實現。
這篇文章利用字串來儲存高精度數值,並實現了兩個字串中數值的運算。
這篇描述兩個字串相乘。
利用字串實現高精度數值運算(一):http://yangtingkun.itpub.net/post/468/469206
上一篇給出了字串表示的數值相加的函式,這一篇繼續描述字串表示數值相乘的演算法。
採用程式碼重用的方法,利用以前處理整數乘法的基礎,加上小數部分的處理。整數部分演算法描述可以參考:http://yangtingkun.itpub.net/post/468/241044
由於包含了小數部分,一個乘法變成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 F_STR_ADD
45 (
46 F_STR_ADD
47 (
48 F_MULTI_STR(V_INTEGER_STR1, V_INTEGER_STR2)
49 || '.'
50 || LPAD(
51 F_MULTI_STR(V_OTHER_STR1, V_OTHER_STR2),
52 V_LENGTH_OTHER_1 + V_LENGTH_OTHER_2,
53 '0'),
54 V_RESULT1
55 ),
56 V_RESULT2
57 );
58 END;
59 /
函式已建立。
下面簡單測試一下函式的功能:
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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-433060/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用字串實現高精度數值運算(四)字串
- 利用字串實現高精度數值運算(三)字串
- 利用字串實現高精度數值運算(一)字串
- 【Mysql學習】算術運算及字串,數值函式MySql字串函式
- 【Mysql 學習】算術運算及字串,數值函式MySql字串函式
- SHELL之數值運算
- Python基礎學習篇-2-數值運算和字串Python字串
- 二進位制數的運算原理與閘電路實現
- 大整數運算C#實現C#
- 計算機中數值和字串怎麼用二進位制表示?計算機字串
- 計算機系統002 – 數值運算計算機
- 計算機系統002 - 數值運算計算機
- 利用版本回退實現誤運算元據恢復
- 集合-運算實現
- 數值計算的可靠性(二)
- (位運算)兩個字串的位運算字串
- 【數值計算方法】常微分方程數值解-數值實驗
- 利用ANTLR4實現一個簡單的四則運算計算器
- vue中使用decimal.js對前端數值型別進行高精度計算VueDecimalJS前端型別
- 複數的四則運算(C語言實現)C語言
- C++ std::list實現大整數加法運算C++
- 字串拼接運算比較字串
- .NET的數學庫NMath實用教程——複數的值操作和邏輯運算
- 如何用位運算實現整數的加減法
- 簡單c++實現複數的四則運算C++
- 第二次作業: 四則運算的實現
- 【數值計算方法】非線性方程求根-數值實驗
- 位運算與SQL實現SQL
- 四則運算實現 (轉)
- 關於int型別數值的運算問題型別
- oracle中字串的大小比較,字串與數字的比較和運算Oracle字串
- javascript怎麼實現算術加法運算JavaScript
- 高精度計算合集
- Shell階段02 shell變數運算(整數運算/小數運算), shell變數案例變數
- SCSS 顏色值運算CSS
- 位運算實現整數與位元組陣列轉換陣列
- 使用位運算、值交換等方式反轉java字串-共四種方法Java字串
- 二進位制、位運算、位移運算